쿼리 메소드 기능 3가지
- 메소드 이름으로 쿼리 생성
- 메소드 이름으로 JPA NamedQuery 호출
- @Query 어노테이션을 사용해서 레포지토리 인터페이스에 쿼리 직접 정의
메소드 이름으로 쿼리 생성
메소드 이름을 분석해서 JPQL 쿼리 실행
예) 이름과 나이를 기준으로 회원 조회 로직 작성
// 순수 JPA
public List<Member> findByUsernameAndAgeGreaterThan(String username, int age) {
return em.createQuery("select m from Member m where m.username = :username and m.age > :age")
.setParameter("username", username)
.setParameter("age", age)
.getResultList();
}
// 스프링 데이터 JPA
List<Member> findByUsernameAndAgeGreaterThan(String username, int age);
쿼리 메소드 필터 조건
JPA 공식 문저 참고 -
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods.query-creation
Spring Data JPA - Reference Documentation
Example 109. Using @Transactional at query methods @Transactional(readOnly = true) public interface UserRepository extends JpaRepository { List findByLastname(String lastname); @Modifying @Transactional @Query("delete from User u where u.active = false") v
docs.spring.io
참고로, 해당 기능은 파라미터 추가될 때마다 메소드 명이 계속 길어진다.
추가로, 엔티티의 필드명이 변경되면 인터페이스에 정의한 메서드 이름도 꼭 함께 변경해야 한다.
이는 실행 시점에 바뀐 부분이나 문제점을 파악할 수 있다.
JPA NamedQuery
JPA 의 NamedQuery 를 호출할 수 있다.
정적 쿼리이기 때문에 로딩 시점에 파싱하여 오류를 확인할 수 있다는 장점이 있다.
// @NamedQuery 어노테이션으로 Named 쿼리 정의
@Entity
@NamedQuery(
name="Member.findByUsername",
query="select m from Member m where m.username = :username")
public class Member {
...
}
// JPA 를 직접 Named 쿼리 호출
public List<Member> findByUsername(String username) {
...
List<Member> resultList = em.createNamedQuery("Member.findByUsername", Member.class)
.setParameter("username", username) .getResultList();
}
// 스프링 데이터 JPA 로 NamedQuery 사용
@Query(name = "Member.findByUsername")
List<Member> findByUsername(@Param("username") String username);
참고로 @Query 를 생략하고 메서드 이름만으로 Named 쿼리를 호출할 수 있다.
스프링 데이터 JPA는 선언한 "도메인 클래스 + .(점) + 메서드 이름"으로 Named 쿼리를 찾아서 실행
만약 실행할 Named 쿼리가 없으면 메서드 이름으로 쿼리 생성 전략을 사용한다.
필요하면 전략을 변경할 수 있지만 권장하지 않는다.
@Query 레포지토리 메소드에 쿼리 정의하기
- @org.springframework.data.jpa.repository.Query 어노테이션을 사용
- 실행할 메서드에 정적 쿼리를 직접 작성하므로 이름 없는 Named 쿼리라 할 수 있음
- JPA Named 쿼리처럼 애플리케이션 실행 시점에 문법 오류를 발견할 수 있음
복잡한 정적 쿼리에 대해선 @Query 기능을 통하여 문제 해결할 수 있지만,
동적 쿼리에 대해선 QueryDSL 을 참고하는게 좋다.
@Query 를 이용한 값 조회
값 타입 (임베디드, 프리미티브 타입)
@Query 를 이용한 DTO 로 직접 조회
DTO 로 직접 조회 하려면 JPA 의 new 명령어 사용해야 한다. 그리고 그에 맞는 DTO 생성자가 필요
참조
- 해당 게시글은 김영한님의 실전 스프링 데이터 JPA 를 참고하여 작성하였습니다.
'JPA' 카테고리의 다른 글
Querydsl 기본 문법 (0) | 2021.04.26 |
---|---|
Querydsl 사용 개요 (0) | 2021.04.25 |
객체지향 쿼리 언어 (0) | 2021.01.25 |
프록시와 연관관계 관리 (0) | 2021.01.20 |
값 타입 (0) | 2021.01.19 |
댓글