티스토리 뷰

WEB/기타

[JPA] 5. Repository query keywords

silverline79 2024. 1. 23. 19:47

5. Repository query keywords

 

Query subject keywords

[https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#appendix.query.method.subject]

Keyword Description
findBy
readBy
getBy
queryBy
searchBy
streamBy
Entity를 조회할 때 사용하는 키워드
find뒤에 엔티티 리턴 타입지정, By뒤엔 칼럼명
속성 이름은 첫 글자는 대문자
Optional<User> findById(Long id);
List<User> findAllById(List<Long> ids);
existsBy 조회 유무를 boolean 타입으로 반환
boolean existsById(Long id);
countBy 검색 결과에 따른 총 record 수를 반환
long countByActive(boolean active);
deleteBy, 
removeBy
결과가 없거나(void) 삭제 횟수를 반환하는 쿼리 메서드를 삭제.
First<number>
Top<number>
조회할 query 결과값 수를 제한하는 Subject Part 키워드는 First, Top
둘은 동일하게 작동되는 키워드이며, find..By 부분의 가운데에 위치
Optional<User> findFirstByOrderByIdDesc();
Optional<User> findTopByOrderByNameAsc();
※ 조회하고자하는 쿼리 수가 1개보다 크거나 페이징처리가 필요할 때에는 Pageable 또는 Sort와 같은 인자를 설정
Page<User> findFirst5ByStatus(String status, Pageable pageable);
Slice<User> findTop10ByType(String type, Pageable pageable);
List<User> findFirst10BySex(String sex, Sort sort);
List<User> findTop3ByStatus(String status, Pageable pageable);→ Pageable과 Sort는 Null을 허용하지 않기 때문에, 해당 인자에 null이
들어갈 경우 에러를 발생시킴
만일 Sort나 Pageable을 사용하고 싶지않을 경우에는 Sort.unsorted(),
Pageable.unpaged()를 사용
Distinct 고유한 결과만 반환하려면 고유한 쿼리를 사용

 

 

Query predicate keywords

[https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods.query-creation]

Keyword 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
IsEquals 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
IsNullNull 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 
( %가 뒤에 추가된 매개 변수)
EndingWith findByFirstnameEndingWith where x.firstname like ?1
 ( %가 앞에 추가된 매개 변수)
Containing findByFirstnameContaining where x.firstname like ?1 
( %가 래핑된 매개 변수)
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)

[Is]

기본 일치 검색

키워드를 생략해도 동일하게 작동되며, 동일한 기능의 키워드로 Equals가 있다.

SELECT u FROM users u WHERE email = ?1;
Optional<User> findByEmail(String email);
Optional<User> findByEmailIs(String email);
Optional<User> findByEmailEquals(String email);

위의 3가지 메서드는 동일하게 작동되며, 통상적으로 키워드를 생략하여 사용

 

[Is]Not

컬럼 단순 불일치 조건

SELECT u FROM users u WHERE email <> ?1;
Optional<User> findByEmailNot(String email);
Optional<User> findByEmailIsNot(String email);

 

[Is]Null, [Is]NotNull

컬럼값이 NULL인 레코드 검색하는 NullNULL이 아닌 레코드를 검색하는 NotNull.

SELECT u FROM users u WHERE u.updatedAt IS NULL;
Optional<User> findByUpdatedAtNull();
Optional<User> findByUpdatedAtIsNull();
SELECT u FROM users u WHERE u.updatedAt IS NOT NULL;
Optional<User> findByUpdatedAtNotNull();
Optional<User> findByUpdatedAtIsNotNull();

 

[Is]Empty, [Is]NotEmpty

컬럼값이 NULL이거나 빈문자열인 레코드 검색하는 Empty 키워드

반대키워드는 NotEmpty

SELECT u FROM users u WHERE u.name IS NULL OR u.name = '';
Optional<User> findByNameEmpty();

 

[Is]True, [Is]False

boolean 타입의 컬럼의 True/False를 검색

SELECT u FROM users u WHERE u.active = true;
List<User> findByActiveTrue();
SELECT u FROM users u WHERE u.active = false;
List<User> findByActiveFalse();

 

And

조건을 and 조건으로 엮고 싶을때 사용

키워드: And

SELECT u FROM users u WHERE u.type = ?1 AND u.active = ?2;
List<User> findByTypeAndActive(String type, String active);

 

IN

여러개의 값으로 검색하는 경우에는 SQL과 마찬가지로 In을 사용한다

SELECT u FROM users u WHERE u.lastname in = ?2;
List<User> findByLastnameIn(List<String> lastname);

 

Or

조건을 or 조건으로 엮고 싶을때 사용

키워드: Or

SELECT u FROM users u WHERE u.type = ?1 OR u.active = ?2;
`List<User> findByTypeOrActive(String type, String active);

 

[Is]GreaterThan, [Is]LessThan, [Is]Between

비교 연산을 지원하는 numeric, datetime 데이터타입의 컬럼에 설정할 수 있는 조건 연산

GreaterThanLessThan 키워드 뒤에 Equal를 붙여서 크거나 같은, 작거나 같은 조건도 설정 가능, Between 키워드로 경계 값을 포함한 범위 검색 가능.

SELECT u FROM users u WHERE u.age < ?1;
List<User> findByAgeLessThan(int age);
SELECT u FROM users u WHERE u.age >= ?1;
List<User> findByAgeGreaterThanEqual(int age);
SELECT u FROM users u WHERE u.age BETWEEN ?1 AND ?2;
List<User> findByAgeBetween(int age1, int age2);

 

[Is]Like, [Is]Containing, [Is]StartingWith, [Is]EndingWith

컬럼의 일부분이 일치하는 레코드를 검색

sql 표준문법에서 character 수와 상관없이 문자열 포함여부를 검색할때 %를 이용다.

Containing(= Contains), StartingWith(= StartsWith), EndingWith(= EndsWith)에서는 편의상 검색할 문자열에 %를 자동으로 붙여줌

Containing에는 양쪽에, StartingWith는 뒤에. EndingWith는 앞에 붙여서 기능을 동작.

Like 키워드의 경우, 인자에 %_를 명시적으로 설정해야하니 이 부분을 주의

_를 이용할 것이 아니라면 편의를 위해 Containing, StartingWith, EndingWith 키워드를 사용하는것을 권장

SELECT u FROM users u WHERE u.email like ?1;
List<User> findByEmailLike(String email);
List<User> findByEmailIsLike(String email);
SELECT u FROM users u WHERE u.email like %?1%;
List<User> findByEmailContains(String email);
List<User> findByEmailContaining(String email);
List<User> findByEmailIsContaining(String email);
SELECT u FROM users u WHERE u.email like ?1%;
List<User> findByEmailStartsWith(String email);
List<User> findByEmailStartingWith(String email);
List<User> findByEmailIsStartingWith(String email);
SELECT u FROM users u WHERE u.email like %?1;
List<User> findByEmailEndsWith(String email);
List<User> findByEmailEndingWith(String email);
List<User> findByEmailIsEndingWith(String email);

Query predicate keywords

Keyword Description
IgnoreCase, 
IgnoringCase
대소문자를 구분하지 않는 비교를 위해 술어 키워드와 함께 사용
AllIgnoreCase, 
AllIgnoringCase
모든 적합한 속성에 대한 대소문자를 무시쿼리 메서드 술어의 어딘가에서 사용
OrderBy 속성 경로와 방향이 뒤따르는 정적 정렬 순서를 지정
(: OrderByFirstnameAscLastnameDesc).

 

IgnoreCase

특정 컬럼의 대소문자를 구분하지 않고 검색

List<User> findByDeviceOsIgnoreCase(String deviceOs);
List<User> findByDeviceOsIgnoringCase(String deviceOs);

 

AllIgnoreCase

모든 컬럼의 대소문자를 구분하지 않고 검색

List<User> findByNameOrEmailAllIgnoreCase(String name, String email);
List<User> findByNameOrEmailAllIgnoringCase(String name, String email);

 

OrderBy...

정렬할 요소를 설정

정렬방식을 컬럼 뒤에 붙일 수 있고, 생략할 경우 오름차순으로 설정

오름차순(Asc), 내림차순(Desc)

List<User> findByActiveOrderByIdDesc(boolean active);
List<User> findByActiveOrderByTypeAscNameAsc(String type, String name);

 

'WEB > 기타' 카테고리의 다른 글

Dto / Entity(=Domain) 차이점  (0) 2024.01.23
[JPA] 6. JPA Auditing  (0) 2024.01.23
[JPA] 4. Repository  (0) 2024.01.23
[JPA] 3. Entity - 연관관계 매핑  (0) 2024.01.20
[JPA] 3. Entity - 설정, 속성  (0) 2024.01.20
댓글