[Spring JPA] 스프링 데이터 JPA 쿼리 메서드 기능
[스프링 데이터 JPA 쿼리 메서드]
목표
순수 JPA리포지토리와 쿼리 메서드 비교하기(이름과 나이를 기준으로 회원 조회하는 쿼리 비교하기)
순수 JPA 리포지토리
1. 순수 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();
}
이 코드는 리포지토리를 생성한 후 쿼리문을 문자열 형태로 만든다.
그 후 이름과 나이를 파리미터 값으로 입력받은 후 조건에 맞는 Member객체를 return하는 형태의 메서드다.
쿼리 메서드 기능 3가지
1. 메서드 이름으로 쿼리 생성
public interface MemberRepository extends JpaRepository<Member, Long> {
List<Member> findByUsernameAndAgeGreaterThan(String username, int age);
}
메서드 이름으로 쿼리를 자동으로 생성할 수 있다. 규칙만 지키면 스프링 데이터 JPA가 메서드 이름을 분석해서 JPQL을 생성하고 실행한다.
이 기능은 엔티티의 필드명이 변경되면 인터페이스에 정의한 메서드 이름도 꼭 함께 변경되어야 한다.
그렇지 않으면 어플리케이션을 시작하는 시점에 오류가 발생하며, 이렇게 로딩 시점에 오류를 인지할 수 있는 것이 스프링 데이터 JPA의 큰 장점이다.
- 참고 : 쿼리 메소드 필터 조건 스프링 데이터 JPA 공식 문서
2. 메서드 이름으로 JPA NamedQuery 호출
@Entity
@NamedQuery(
name="Member.findByUsername",
query="select m from Member m where m.username = :username")
public class Member {
...
}
public class MemberRepository {
public List<Member> findByUsername(String username) {
List<Member> resultList = em.createNamedQuery("Member.findByUsername", Member.class)
.setParameter("username", username)
.getResultList();
}
}
엔티티 위에 메서드 이름과 쿼리를 지정한 후, 리포지토리에서 엔티티에서 지정한 이름으로 메서드를 호출하여 실행한다.
스프링 데이터 JPA는 도메인 클래스 + . + 메서드 이름으로 NamedQuery를 다른 쿼리 메서드보다 먼저 찾아서 실행한다.
3. @Query 어노테이션을 사용해서 리파지토리 인터페이스에 쿼리 직접 정의
public interface MemberRepository extends JpaRepository<Member, Long> {
@Query("select m from Member m where m.username= :username and m.age = :age")
List<Member> findUser(@Param("username") String username, @Param("age") int age);
}
@org.springframework.data.jpa.repository.Query 어노테이션을 사용한다.
실행할 메서드에 정적 쿼리를 직접 작성하므로 이름 없는 NamedQuery라 할 수 있으며, JPA NamedQuery처럼 어플리케이션 실행 시점에 문법 오류를 발견하는 매우 큰 장점이다.