JPA에서 쿼리 메서드를 정의하는 방법에 대해서 알아보자.
1. QueryLookup 전략
CREATE
메서드 이름을 분석해서 만듬USE_DECLARED_QUERY
미리 정의해둔 쿼리를 찾아서 사용CREATE_IF_NOT_FOUND
기본 전략 - 미리 정의해둔 쿼리 찾아서 없으면 메서드 이름 분석해서 만듬
CREATE는 메서드 이름을 통해서 쿼리를 매핑해 준다. 예를 들면 findById
findTop10ByTitleContainsOrderByIdDesc
와 같이 실제 쿼리를 작성할 때 처럼 명명 규칙이 존재한다.
두번째는 @Query 어노테이션을 활용한 방법이다. 일반적으롱 JPQL 을 사용해서 작성하지만, navtive Query를 원하는 경우에는 nativeQuery 프로퍼티의 값을 true로 설정하면 된다.
@Query(“select p from Post”, nativeQuery =true)
세번째가 쿼리를 만들어내는 기본 전략이다. 1번 2번을 합친것이다. 2번에서 정의한 쿼리가 없으면 1번을 통해서 만든다.
해당 QueryLookUp 전략은 @EnableJpaRepository
에 queryLookupStrategy
프로퍼티를 통해서 변경할 수 있지만, 굳이 하지 않아도 된다. 관련 소스를 보는 것만으로 족함(예를 들면, @Query, @NamedQuery를 쿼리 메서드 위에 정의했을 때 우선순위가 어떻게 될까? )
2. 예제 코드
@Data
@Entity
@Table
public class Post {
@Id
@GeneratedValue
private Long id;
private String title;
id, title만 있는 Post 엔티티
public interface PostRepository extends JpaRepository<Post, Long> {
Post findByTitl(String title);
}
title을 통해서 Post를 찾는 쿼리 메서드 작성
3. 테스트
@Test
public void queryMethodTest() {
// just context load ...
}
아무 것도 작성하지 않고 테스트를 돌려보자. 쿼리 메서드가 잘 만들었으면, 빈을 초기화 하고 등록할 때 문제없이 잘 동작해야 한다.
Caused by: org.springframework.data.mapping.PropertyReferenceException: No property titl found for type Post! Did you mean 'title'?
예외가 난다. 쿼리 메서드를 만들 때 Post의 property명을 titl로 기입해서 PropertyReferenceException
이 발생했다. findByTitle()
로 수정하고 테스트를 돌리면 성공
@Test
public void queryMethodTest() {
Post post = new Post();
post.setTitle("post1");
postRepository.save(post);
Post result = postRepository.findByTitle("post1");
Assert.assertEquals(result.getTitle(), "post1");
}
쿼리 메서드만 잘 만들어 지는지 말고, 잘 동작하는지 테스트 코드 작성하고 테스트
성공! 😀
4. 참고
📚 Related Posts
- JPA - 값 타입(6)
- JPA - 프록시와 연관관계(5)
- JPA - 다양한 연관관계 매핑(4)
- JPA - 연관관계 매핑(기초)(3)
- JPA - 엔티티 매핑(2)
- JPA - 영속성 관리(1)
- [JPA] 연관관계 매핑 (연관관계 편의 메서드)
- [JPA] 엔티티 설계시 주의사항들
- [JPA] Auditing 사용하기
- [JPA]@Transactional를 통한 Optimization
- [JPA] 엔티티 일부 데이터만 조회하는 Projection
- [JPA] save메서드로 살펴보는 persist와 merge 개념
- [JPA] 쿼리메서드(Lookup 전략)
- [JPA] QueryDSL 설정방법
- [JPA] null 처리
- [JPA] 연관관계 매핑 기초(다대일, 연관관계 주인)
- SpringBoot, JPA, H2를 이용한 간단한API 작성
- [JPA] proxy, fetch 전략
- [JPA] 도메인 클래스 컨버터란?
- [JPA] Custom Repository 만들기
- [JPA] Casecade 옵션