1. 개요

간단한 쿼리의 경우 코드에서 해당 메서드 이름을 살펴보는 것만으로 쿼리가 무엇이어야 하는지 쉽게 도출할 수 있습니다 .

이 예제에서는 Spring Data JPA 가 메서드 명명 규칙의 형태로 이 아이디어를 활용 하는 방법을 살펴보겠습니다 .

2. Spring의 파생 쿼리 메서드 구조

파생 메서드 이름에는 첫 번째 By 키워드 로 구분되는 두 가지 주요 부분이 있습니다 .

List<User> findByName(String name)

find 와 같은 첫 번째 부분 소개 자이고 ByName 과 같은 나머지 부분 criteria 입니다.

Spring Data JPA는 find , read , query , count 및  get 을 지원 합니다. 따라서 queryByName 을 수행할 수 있었고 Spring Data는 동일하게 작동합니다.

Distinct , First  또는  Top 을 사용하여 중복을 제거하거나 결과 집합을 제한 할 수도 있습니다  .

List<User> findTop3ByAge()

조건 부분에는 쿼리의 엔터티별 조건식이 포함됩니다. 엔터티의 속성 이름과 함께 조건 키워드를 사용할 수 있습니다.

잠시 후에 살펴보겠지만 표현식을 AndOr 와 연결할 수도 있습니다.

3. 샘플 신청

먼저 Spring Data JPA를 사용하는 애플리케이션 이 필요 합니다 .

해당 애플리케이션에서 엔터티 클래스를 정의해 보겠습니다.

@Table(name = "users")
@Entity
class User {
    @Id
    @GeneratedValue
    private Integer id;
    
    private String name;
    private Integer age;
    private ZonedDateTime birthDate;
    private Boolean active;

    // standard getters and setters
}

저장소도 정의해 보겠습니다.

Spring Data Repository 유형 중 하나인 JpaRepository 를 확장 합니다 .

interface UserRepository extends JpaRepository<User, Integer> {}

여기에서 파생된 쿼리 메서드를 모두 배치합니다.

4. 평등 조건 키워드

완전 같음은 쿼리에서 가장 많이 사용되는 조건 중 하나입니다. 쿼리에서 = 또는 IS 연산자 를 표현하는 몇 가지 옵션이 있습니다.

정확히 일치 조건에 대한 키워드 없이 속성 이름을 추가할 수 있습니다.

List<User> findByName(String name);

가독성을 위해 Is 또는 Equals 를 추가할 수 있습니다 .

List<User> findByNameIs(String name);
List<User> findByNameEquals(String name);

이 추가 가독성은 부등식을 대신 표현해야 할 때 유용합니다.

List<User> findByNameIsNot(String name);

이것은 findByNameNot(String) 보다 훨씬 더 읽기 쉽습니다 !

null 같음은 특수한 경우 이므로 = 연산자를 사용하면 안 됩니다. Spring Data JPA는 기본적으로 null 매개변수 를 처리합니다. 따라서 같음 조건에 대해 null 값을 전달하면 Spring은 생성된 SQL에서 쿼리를 IS NULL로 해석합니다.

IsNull  키워드를 사용하여 쿼리에 IS NULL 기준을 추가 할 수도 있습니다 .

List<User> findByNameIsNull();
List<User> findByNameIsNotNull();

IsNullIsNotNull 모두 메서드 인수가 필요하지 않습니다.

인수가 필요하지 않은 키워드가 두 개 더 있습니다.

TrueFalse 키워드를 사용 하여 부울 유형 에 대한 동등 조건을 추가 할 수 있습니다.

List<User> findByActiveTrue();
List<User> findByActiveFalse();

물론 우리는 때때로 정확한 평등보다 더 관대한 것을 원하므로 우리가 무엇을 할 수 있는지 봅시다.

5. 유사 조건 키워드

속성 패턴으로 결과를 쿼리해야 하는 경우 몇 가지 옵션이 있습니다.

StartingWith 를 사용하여 값으로 시작하는 이름을 찾을 수 있습니다 .

List<User> findByNameStartingWith(String prefix);

대략 이것은 "WHERE name LIKE 'value%' " 로 번역됩니다 .

값으로 끝나는 이름을 원하는 경우 EndingWith 가 원하는 것입니다.

List<User> findByNameEndingWith(String suffix);

또는 Containing 을 사용하여 값을 포함하는 이름을 찾을 수 있습니다 .

List<User> findByNameContaining(String infix);

위의 모든 조건을 사전 정의된 패턴 표현식이라고 합니다. 따라서 이러한 메서드가 호출될 때 인수 내에 연산자 를 추가할 필요가 없습니다 .

하지만 좀 더 복잡한 일을 한다고 가정해 봅시다. 이름이 a 로 시작하고 b 를 포함 하고 c  로 끝나는  사용자를 가져와야 한다고 가정해 보겠습니다 .

이를 위해 Like 키워드 와 함께 자체 LIKE를 추가할 수 있습니다 .

List<User> findByNameLike(String likePattern);

그런 다음 메서드를 호출할 때 LIKE 패턴을 전달할 수 있습니다.

String likePattern = "a%b%c";
userRepository.findByNameLike(likePattern);

지금은 이름에 대해 충분합니다. User 에서 다른 값을 시도해 봅시다 .

6. 비교 조건 키워드

또한 LessThanLessThanEqual 키워드를 사용하여 <<= 연산자 를 사용하여 레코드를 주어진 값과 비교할 수 있습니다.

List<User> findByAgeLessThan(Integer age);
List<User> findByAgeLessThanEqual(Integer age);

반대 상황에서는 GreaterThanGreaterThanEqual 키워드를 사용할 수 있습니다.

List<User> findByAgeGreaterThan(Integer age);
List<User> findByAgeGreaterThanEqual(Integer age);

또는 Between 을 사용하여 두 연령대 사이의 사용자를 찾을 수 있습니다 .

List<User> findByAgeBetween(Integer startAge, Integer endAge);

또한 In 사용에 대해 일치시킬 연령 컬렉션을 제공할 수 있습니다 .

List<User> findByAgeIn(Collection<Integer> ages);

사용자의 생년월일을 알고 있으므로 지정된 날짜 이전 또는 이후에 태어난 사용자를 쿼리할 수 있습니다.

이를 위해  Before 와  After 를 사용합니다.

List<User> findByBirthDateAfter(ZonedDateTime birthDate);
List<User> findByBirthDateBefore(ZonedDateTime birthDate);

7. 여러 조건식

AndOr 키워드 를 사용하여 필요한 만큼 많은 표현식을 결합할 수 있습니다 .

List<User> findByNameOrBirthDate(String name, ZonedDateTime birthDate);
List<User> findByNameOrBirthDateAndActive(String name, ZonedDateTime birthDate, Boolean active);

우선 순위는 Java와 마찬가지로 And then  Or 입니다.

Spring Data JPA는 우리가 추가할 수 있는 표현식의 수에 제한을 두지 않지만 여기서 미친 짓을 해서는 안 됩니다. 긴 이름은 읽을 수 없고 유지하기 어렵습니다. 복잡한 쿼리 의 경우 대신 @Query 어노테이션을 살펴보세요 .

8. 결과 정렬

다음으로 정렬에 대해 살펴보겠습니다.

OrderBy 를 사용하여 사용자 이름을 알파벳순으로 정렬하도록 요청할 수 있습니다 .

List<User> findByNameOrderByName(String name);
List<User> findByNameOrderByNameAsc(String name);

오름차순은 기본 정렬 옵션이지만 대신 Desc 를 사용 하여 역순으로 정렬할 수 있습니다.

List<User> findByNameOrderByNameDesc(String name);

9. CrudRepository  에서 findOnefindById 비교

Spring 팀은 Spring Boot 2.x를 사용 하여 CrudRepository 에 몇 가지 주요 변경 사항을 적용했습니다 . 그중 하나는 findOnefindById 로 이름을 바꾸는 것입니다 .

이전 Spring Boot 1.x에서는 기본 키로 엔터티를 검색하려고 할 때 findOne 을 호출했습니다.

User user = userRepository.findOne(1);

Spring Boot 2.x부터는 findById 로 동일한 작업을 수행할 수 있습니다 .

User user = userRepository.findById(1);

findById()  메서드는 이미 CrudRepository에 정의 되어 있습니다 . 따라서 CrudRepository 를 확장하는 사용자 지정 저장소에서 명시적으로 정의할 필요가 없습니다 .

10. 결론

이 기사에서는 Spring Data JPA의 쿼리 파생 메커니즘에 대해 설명했습니다. 속성 조건 키워드를 사용하여 Spring Data JPA 리포지토리에서 파생된 쿼리 메서드를 작성했습니다.

이 기사의 소스 코드는 GitHub 프로젝트 에서 사용할 수 있습니다 .

Persistence footer banner