Home Query Method
Post
Cancel

Query Method

1
2
3
public interface UserRepository extends JpaRepository<User, Long> {
    List<User> findByName(String name);
}
  • Query Method란 위의 코드처럼 메소드의 이름으로 쿼리를 생성해주는 기능이다.
    • Spring Data Jpa가 메소드 이름을 분석해 JPQL을 생성해 실행해준다.

KeyWord

보통 select Query만 많이 사용하고 나머지는 select로 조회한 것을 사용해 처리하거나 Delete같은 경우 Jpa에서 제공하는 Method를 많이 사용한다.

  • Select Query
    • find…By, read…By, get…By, query…By, search…By, stream…By
    • 위의 접두어 모두 같은 역할을 수행하고 일반적으로 findBy를 가장 많이 사용한다.
    • …은 Entity가 들어갈 수 있는것을 의미한다.
      • ex) findUserByName or findUsersByName
        • List반환 일 경우 s를 붙여 사용한다.
      • 하지만 보통 Repository를 정의할 때 JpaRepository<User, Long> 으로 Entity명시를 해주기 때문에 많이 사용하지는 않는다.
  • delete Query
    • delete…By, remove…By
  • limit
    • …First..., ...Top...
    • ex) List findTop6ByName(String name)
      • Name으로 조회 했을 때 상위 6개만 조회
  • ETC..
    • exists…By
    • count…By

After, Before

1
2
3
4
public interface UserRepository extends JpaRepository<User, Long> {
    List<User> findByCreatedAtAfter(LocalDateTime day);
    List<User> findByCreatedAtBefore(LocalDateTime day);
}
  • 생성되는 Query가 특정 column에 대해 param보다 크거나 작은지를 비교하기 때문에 시간이 아닌 경우에도 대소 비교가 가능한 Data라면 사용이 가능하다.
  • 시간 비교이외에는 Before, After가 가독성 측면에서 별로 좋지 않아 다른 Data에는 사용이 권장되지 않는다.

데이터 범위

  • Greater, Less
    1
    2
    3
    4
    5
    6
    
      public interface UserRepository extends JpaRepository<User, Long> {
          List<User> findByCreatedAtGreaterThan(LocalDateTime day);
          List<User> findByCreatedAtGreaterThanEqual(LocalDateTime day);
          List<User> findByCreatedAtLessThan(LocalDateTime day);
          List<User> findByCreatedAtLessThanEqual(LocalDateTime day);
      }
    
  • Between
    1
    2
    3
    4
    
      public interface UserRepository extends JpaRepository<User, Long> {
          List<User> findByCreatedAtBetween(LocalDateTime day1, LocalDateTime day2);
          List<User> findByIdBetween(Long id1, Long id2);
      }
    
    • 양 끝의 값을 포함해 사이의 값인 경우 조회 된다.

데이터의 유무

  • IS_EMPTY, IS_NOT_EMPTY

    1
    2
    3
    4
    5
    6
    7
    8
    
      ...
      @Entity
      public class User {
    
          ...
          @OneToMany(fetch = FetchType.EAGER)
          private List<Address> address;
      }
    
    1
    2
    
      List<User> findByAddressIsNotEmpty();
      List<User> findByAddressIsEmpty();
    
    • Collection property에만 사용할 수 있다.
  • IS_NULL, IS_NOT_NULL

    1
    2
    
      List<User> findByNameIsNotNull();
      List<User> findByNameIsNull();
    
    • 값 자체가 Null인지 아닌지 파악할 때 사용할 수 있다.
  • In, NotIn

    1
    2
    
      List<User> findByNameIn(List<String> names);
      List<User> findByNameNotIn(List<String> names);
    

문자열 Query

  • StartingWith, EndingWith, Containing, Like

    1
    2
    3
    4
    
      List<User> findByNameStartingWith(String name); // 시작하는 
      List<User> findByNameEndingWith(String name); // 끝나는
      List<User> findByNameContaining(String name); // 포함하는
      List<User> findByNameLike(String name);
    
    • 앞의 3개 KeyWord는 like를 한번 Wrapping한것이다.
    1
    2
    3
    
     userRepository.findByNameLike("km%"); // StartingWith("km")과 같다.
     userRepository.findByNameLike("%ms"); // EndingWith("ms")와 같다.
     userRepository.findByNameLike("%m%"); // Containing("m")과 같다.
    

limit

1
List<User> findTop1ByNameOrderByIdDesc(String name);
  • Top1을 통해 가장 앞의 하나는 가져올 수 있지만 Last keyword가 없기 때문에 OrderBy를 사용해야한다.
  • Id를 역순으로 정렬한 뒤 name이 일치하는 것 중 가장 처음 값을 반환한다.

정렬

  • Query Method만 사용
    1
    
      List<User> findFirstByNameOrderByIdDescEmailAsc(String name);
    
    • 가장 앞의 조건이 1순위 이며 1순위가 같으면 다음 순위의 조건 기준으로 정렬한다.
    • 위의 QueryMethod는 Id 내림차순, Email 오름차순으로 정렬한 뒤 param과 일치하는 가장 처음의 entity를 반환한다.
    • Method명이 길어져서 가독성이 안좋아질 수 있다.
  • Sort 사용
    1
    
      List<User> findFirstByName(String name, Sort sort);
    
    1
    
      userRepository.findFirstByName("kms", Sort.by(Sort.Order.desc("id"), Sort.Order.asc("email")));
    
    • Sort기준을 Parameter로 받아서 사용할 수 있다.

페이징

  • Paging의 경우 JpaRespository interface를 사용하면 별도의 코드없이 사용 할 수 있다.
    • Page Interface의 경우 Slice를 상속받아 구현 되어 있다. Slice는 Data의 일부분을 가지는 Class이다.
  • Pageable은 Page를 요청하는 요청 값이다.
1
Page<User> findByName(String name, Pageable pageable);
  • 사용 코드

    1
    
      userRepository.findByName("kms", PageRequest.of(0, 1, Sort.by(Sort.Order.desc("id"))));
    
    • Name이 kms인 entity를 id역순으로 정렬한 뒤 Page당 Entity개수 1개로 나누었을 때 0번째 page를 반환한다.
    • getContent()를 통해 Page객체의 값을 사용할 수 있다.

Native Query

  • Query Method로 이름을 정하기 애매한 경우가 있을 수 있다. 이런경우 직접 DB의 Query문을 작성해 사용할 수 있다.

    1
    2
    3
    4
    5
    
      // Entity Type, PK Type
      public interface UserRepository extends JpaRepository<User, Long> {
          @Query(value = "select * from user where name = 'kms';", nativeQuery = true)
          Map<String, Object> findWithNativeQuery();
      }
    
This post is licensed under CC BY 4.0 by the author.