QueryMethod 살펴보기
public interface JpaUserRepository extends JpaRepository<JpaUser, Long> {
Set<JpaUser> findByName1(String name);
Optional<JpaUser> findByName2(String name);
List<JpaUser> findByName3(String name);
}
다음과 같이 리턴형을 자유롭게 지정하여 여러가지 값을 받을 수 있으나 Runtime시 에러가 날 수 있기 때문에 잘 지정해줘야함.
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.details
Spring JPA 공식문서를 통해 Query Method를 어떻게 다루는지 상세히 볼 수 있음
find...By, read...By등과 같이 자유도 있게 select query문을 사용할 수 있다.
JpaUser findByEmail(String email);
JpaUser getByEmail(String email);
JpaUser readByEmail(String email);
JpaUser queryByEmail(String email);
JpaUser searchByEmail(String email);
JpaUser streamByEmail(String email);
JpaUser findJpaUserByEmail(String email);
JpaUser findSomethingByEmail(String email);
그러나 높은 자유도로 인해 다음과 같은 query method도 가능하지 않을까라는 생각이 떠오를 수도있다.
JpaUser findSomethingByEmail(String email);
JpaUser findFirst1ByName(String name);
JpaUser findTop1ByName(String name);
List<JpaUser> findFirst2ByName(String name);
List<JpaUser> findTop2ByName(String name);
Refer Doc에서 나와있는 First,Top과 같은 접두어는 다음과 같이 사용하면서 정상작동한다.
JpaUser findLast1ByName(String name);
그러나 다음과 같이 제공되어있지 않은 문자열은 무시가 되어 findByName과 같이 동작하게 되는데 Last1을 동작하게 해주고 싶다면 order by를 역순으로 지정해준후 findTop1ByName으로 찾아와야 한다.
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#appendix.query.method.predicate
해당 정보와 같이 여러가지 조건을 개발자가 추가할 수 있다.
@Test
void 다양한쿼리메서드(){
// ===================== QueryMethod + 조건 추가====================
System.out.println("findByEmailAndName : "+jpaUserRepository.findByEmailAndName("ojysep2@gmail.com","seung"));
System.out.println("findByEmailOrName : "+jpaUserRepository.findByEmailOrName("ojysep2@gmail.com","ryu"));
// System.out.println("findByCreatedAtAfter : "+jpaUserRepository.findByCreatedAtAfter(LocalDateTime.now().minusDays(1L)));
jpaUserRepository.findByCreatedAtAfter(LocalDateTime.now().minusDays(1L)).forEach(System.out::println);
jpaUserRepository.findByIdAfter(2L).forEach(System.out::println);
System.out.print("findByCreatedAtGreaterThan : ");
jpaUserRepository.findByCreatedAtGreaterThan(LocalDateTime.now().minusDays(1L)).forEach(System.out::println);
System.out.print("findByCreatedAtGreaterThanEqual : ");
jpaUserRepository.findByCreatedAtGreaterThanEqual(LocalDateTime.now().minusDays(1L)).forEach(System.out::println);
System.out.print("findByCreatedAtBetween : ");
jpaUserRepository.findByCreatedAtBetween(
LocalDateTime.now().minusDays(1L),
LocalDateTime.now().plusDays(1L)).forEach(System.out::println);
System.out.print("findByIdBetween : ");
jpaUserRepository.findByIdBetween(1L,4L).forEach(System.out::println);
System.out.println("findByIdIsNotNull : "+jpaUserRepository.findByIdIsNotNull());
// System.out.println("findByAddressIsNotEmpty : "+jpaUserRepository.findByAddressIsNotEmpty());
jpaUserRepository.findByNameIn(Lists.newArrayList("ryu", "seung")).forEach(System.out::println);
System.out.println("findByNameStartingWith : "+jpaUserRepository.findByNameStartingWith("ry"));
System.out.println("findByNameEndingWith : "+jpaUserRepository.findByNameEndingWith("ng"));
System.out.println("findByNameStartingWith : "+jpaUserRepository.findByNameContains("bo"));
// like는 코드 가독성을 해침!
System.out.println("findByNameLike : "+jpaUserRepository.findByNameLike("%y%"));
// Is,Equals 은 코드 가독성을 높이는 친구들임
// findByName == findByNameIs == findByNameEquals
}
코드가 너무 더럽지 않게 가독성있게 name하고 구성하는 것이 중요하다...
@Test
void 정렬쿼리메소드(){
System.out.println("findTop1ByName : "+jpaUserRepository.findTop1ByName("ryu"));
System.out.println("findTopByNameOrderByIdDesc : "+jpaUserRepository.findTopByNameOrderByIdDesc("ryu"));
System.out.println("findAllOrderByIdDesc : ");
jpaUserRepository.findAll(Sort.by(Sort.Direction.DESC, "id")).forEach(System.out::println);
System.out.println("findFirstByNameOrderByIdDescEmailAsc : ");
jpaUserRepository.findFirstByNameOrderByIdDescEmailAsc("ryu").forEach(System.out::println);
System.out.println("findFirstByNameWithSortParam : ");
jpaUserRepository.findFirstByName("ryu", Sort.by(Sort.Order.desc("id"),Sort.Order.asc("email")))
.forEach(System.out::println);
jpaUserRepository.findFirstByName("ryu", getSort()).forEach(System.out::println);
}
private Sort getSort(){
return Sort.by(
Sort.Order.desc("id"),
Sort.Order.asc("email"),
Sort.Order.desc("createdAt"),
Sort.Order.asc("updatedAt")
);
}
코드에 나와있는 것 이상으로 Page,Pageable,Slice 인터페이스를 보면 사용 가능한 기능들이 많다.
^+click으로 한번씩 확인해보는 것이 좋을 것 같다.
@Test
void 쿼리로페이징처리(){
System.out.println("findByNameWithPaging : " + jpaUserRepository.findByName(
"ryu",
PageRequest.of(0, 1, Sort.by(Sort.Order.desc("id")))).getContent()); // 0페이지 요청+페이지당 데이터 1개+id역순
System.out.println("findByNameWithPaging : " + jpaUserRepository.findByName(
"ryu",
PageRequest.of(0, 1, Sort.by(Sort.Order.desc("id")))).getTotalElements());
}
출처 : 한 번에 끝내는 Java/Spring 웹 개발 마스터 초격차 패키지 Online.