스프링 데이터 JPA가 제공하는 쿼리 메서드 기능을 살펴보자.
스프링 데이터 JPA는 메소드 이름을 분석해서 JPQL을 생성하고 실행한다. 이름과 나이를 기준으로 회원을 조회해보자.
public interface MemberRepository extends JpaRepository<Member, Long> {
List<Member> findByUsernameAndAgeGreaterThan(String username, int age);
}
자세한 쿼리 메소드 필터 조건은 링크를 참고하자.
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods.query-creation
참고: 이 기능은 엔티티의 필드명이 변경되면 인터페이스에 정의한 메서드 이름도 꼭 함께 변경해야 한다. 그렇지 않으면 애플리케이션 시작하는 시점에 오류가 발생한다. 이렇게 애플리케이션 로딩 시점에 인지할 수 있는 것이 스프링 데이터 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();
}
}
@Query(name = "Member.findByUsername")
List<Member> findByUsername(@Param("username") String username);
+) @Query를 생략하고 메서드 이름만으로 Named 쿼리를 호출할 수 있다.
public interface MemberRepository extends JpaRepository<Member, Long> {
List<Member> findByUsername(@Param("username") String username);
}
스프링 데이터 JPA는 선언한 "도메인 클래스 + .(점) + 메서드 이름"으로 Named 쿼리를 찾아서 실행한다. 만약 실행할 Named 쿼리가 없으면 메서드 이름으로 쿼리 생성 전략을 사용한다.
참고: 스프링 데이터 JPA를 사용하면 실무에서 Named Query를 직접 등록해서 사용하는 일은 드물다. 대신 @Query 를 사용해서 리포지토리 메소드에 쿼리를 직접 정의한다.
해당 기능은 실행할 메서드에 정적 쿼리를 직접 작성하므로, 이름 없는 Named 쿼리라 할 수 있다. JPA Named 쿼리처럼 애플리케이션 실행 시점에 문법 오류를 발견할 수 있다는 장점이 있다.
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") intage);
}
참고: 실무에서는 메소드 이름으로 쿼리 생성 기능은 파라미터가 증가하면 메서드 이름이 매우 지저분해진다. 따라서 @Query 기능을 자주 사용하게 된다.