Query작성중 마주친 빨간녀석...
nativeQuery를 이용한 SQL을 사용하면 쉽지만... 그냥 JPQL로 구현해보고싶었다. 그리고 두 문장의 차이점도 알아보고싶다.
JPA 기본 문법
// @Repository 이 어노테이션은 생략 가능
public interface EntityRepository extends JpaRepository<T, ID> {}
// T: 엔티티 타입
// ID: 식별자 타입
주요 메서드
메서드 | 설명 |
<S extends T> S save(S) | 새로운 엔티티는 저장하고, 이미 있는 엔티티는 병합 |
delete(T) | 엔티티 하나를 삭제 |
Optional<T> findById(ID) | ID로 엔티티 하나를 조회 |
List<T> findAll(...) | 모든 엔티티를 조회 정렬(Sort)이나 페이징(Pageable) 조건을 파라미터로 제공 가능 |
쿼리 생성
- 기본 문법
이름+키워드[+By+컬럼명[+키워드]]
- 이름 규칙 : 메서드 이름에 관한 규칙 (~By+필드명)
쿼리 종류 | 이름 규칙 |
조회 | find...By, read...By, query...By, get...By |
COUNT | count...By 반환타입 long |
EXISTS | exists...By 반환타입 boolean |
삭제 | delete...By, remove...By |
DISTINCT | findDistinct, findMemberDistinctBy |
LIMIT | findFirst3, findFirst, findTop, findTop3 |
cf) 엔티티의 필드명이 변경되면 반드시 인터페이스에 정의한 메서드 이름도 함께 변경
(∵ 애플리케이션을 시작하는 시점에 오류 발생)
- 키워드 종류
Keywords | Sample | JPQL snippet |
Distinct | findDistinctByLastnameAndFirstname | select distinct … where x.lastname = ?1 and x.firstname = ?2 |
And | findByLastnameAndFirstname | … where x.lastname = ?1 and x.firstname = ?2 |
Or | findByLastnameOrFirstname | … where x.lastname = ?1 or x.firstname = ?2 |
Is, Equals |
findByFirstname, findByFirstnameIs, findByFirstnameEquals |
… where x.firstname = ?1 |
Between | findByStartDateBetween | … where x.startDate between ?1 and ?2 |
LessThan | findByAgeLessThan | … where x.age < ?1 |
LessThanEqual | findByAgeLessThanEqual | … where x.age <= ?1 |
GreaterThan | findByAgeGreaterThan | … where x.age > ?1 |
GreaterThanEqual | findByAgeGreaterThanEqual | … where x.age >= ?1 |
After | findByStartDateAfter | … where x.startDate > ?1 |
Before | findByStartDateBefore | … where x.startDate < ?1 |
IsNull, Null |
findByAge(Is)Null | … where x.age is null |
IsNotNull, NotNull |
findByAge(Is)NotNull | … where x.age not null |
Like | findByFirstnameLike | … where x.firstname like ?1 |
NotLike | findByFirstnameNotLike | … where x.firstname not like ?1 |
StartingWith | findByFirstnameStartingWith | … where x.firstname like ?1 (parameter bound with appended %) |
EndingWith | findByFirstnameEndingWith | … where x.firstname like ?1 (parameter bound with prepended %) |
Containing | findByFirstnameContaining | … where x.firstname like ?1 (parameter bound wrapped in %) |
OrderBy | findByAgeOrderByLastnameDesc | … where x.age = ?1 order by x.lastname desc |
Not | findByLastnameNot | … where x.lastname <> ?1 |
In | findByAgeIn(Collection<Age> ages) | … where x.age in ?1 |
NotIn | findByAgeNotIn(Collection<Age> ages) | … where x.age not in ?1 |
True | findByActiveTrue() | … where x.active = true |
False | findByActiveFalse() | … where x.active = false |
IgnoreCase | findByFirstnameIgnoreCase | … where UPPER(x.firstname) = UPPER(?1) |
쿼리 메서드의 파라미터에는 Pageable, Slice, Sort를 파라미터로 사용 가능
Page<User> findByLastname(String lastname, Pageable pageable);
Slice<User> findByLastname(String lastname, Pageable pageable);
List<User> findByLastname(String lastname, Sort sort);
List<User> findByLastname(String lastname, Pageable pageable);
JPQL사용(단독 사용은 하지않고 보통 QueryDSL등과 함께 사용)
유일하지만 매우 큰 장점은 '특정 DB SQL에 의존하지 않는다.'이다. 하지만 여러 단점이 있다.
1. 결국 SQL로 변환
2. 기본 문자열로 작성되기 때문에 컴파일시 에러를 발생하지 않아 배포시 문제 발생 가능
3. 동적 쿼리 언어로 작성하는것에 효율성이 떨어짐, 예를들어 조건으로 분기를 나눠 쿼리 실행할때 A인 케이스와 B인 케이스를 따로 나눠서 작성 및 실행
4. DB에 매핑하여 실행되어 속도적인 부분에서도 성능이 높지 않음
특징은 까다롭다.
- 엔티티와 속성의 대소문자 구분
- 엔티티 어노테이션으로 name을 지정하지 않으면 클래스 이름이 엔티티 name으로 지정됨
- 테이블 이름이 아닌 엔티티 이름을 사용
- 별칭의 사용은 필수적이나 as는 생략이 가능
Native Query
장점
1. DB에 직접적으로 쿼리 실행
2. SQL 언어를 전체적으로 사용 가능
3. 여러 조인이나 복잡한 쿼리를 작성할 때 직관적이며 이해가 쉬움
단점
1. 결과의 반환 형태가 Object 리스트로 고정
2. 입력된 값을 매개변수로 바인딩하거나 따로 유효성 검사가 필요할 수 있음
지극히 개인적인 판단으로 글을 작성하였고 내가 모르는 장점이나 단점들도 많이 있겠지만
개인적으로는... 커스텀도 직관적이고 성능도 비교적 높은 NativeQury를 사용하는 것이 좋은것 같다.
하지만 아직도..... 이 글을 쓰게된 이유인 맨위에 녀석이 빨간글씨가 되는 이유는 아직도 모르겠다......
'Backend > Spring | SpringBoot' 카테고리의 다른 글
[JPA] insert...ing (0) | 2024.03.04 |
---|---|
[JPA] Insert 방법 (0) | 2024.02.29 |
[Spring] H2 및 JPA Properties적용 (0) | 2024.02.22 |
[Error Log] PropertyReferenceException, NoSuchBeanDefinitionException, UnsatisfiedDependencyException (0) | 2024.02.21 |
[Spring] JPA 기본키 전략 (0) | 2024.02.21 |