메소드 이름을 분석해서 JPQL 쿼리 실행합니다. 예를 들어, 이름과 나이를 기준으로 회원을 조회하려면?
public List<Member> findByUsernameAndAgeGreaterThan(String username, int age) {
return em.createQuery("select m from Member m where m.username = :usernameand m.age > :age")
.setParameter("username", username)
.setParameter("age", age)
.getResultList();
}
@Test
void findByUsernameAndAgeGreaterThan() {
Member m1 = new Member("AAA", 10);
Member m2 = new Member("AAA", 20);
memberJpaRepository.save(m1);
memberJpaRepository.save(m2);
List<Member> result = memberJpaRepository.findByUsernameAndAgeGreaterThan("AAA", 15);
assertThat(result.get(0).getUsername()).isEqualTo("AAA");
assertThat(result.get(0).getAge()).isEqualTo(20);
assertThat(result.size()).isEqualTo(1);
}
당연히 테스트는 성공합니다. 로직상 아무 문제가 없죠. 단지 코드를 직접 짜야한다는게 문제가 되는겁니다.
public interface MemberRepository extends JpaRepository<Member, Long> {
List<Member> findByUsernameAndAgeGreaterThan(String username, int age);
}
@Test
void findByUsernameAndAgeGreaterThan() {
Member m1 = new Member("AAA", 10);
Member m2 = new Member("AAA", 20);
memberRepository.save(m1);
memberRepository.save(m2);
List<Member> result = memberRepository.findByUsernameAndAgeGreaterThan("AAA", 15);
assertThat(result.get(0).getUsername()).isEqualTo("AAA");
assertThat(result.get(0).getAge()).isEqualTo(20);
assertThat(result.size()).isEqualTo(1);
}
똑같이 테스트가 성공하죠.
이처럼 스프링 데이터 JPA는 메소드 이름을 분석해서 JPQL을 생성하고 실행합니다. 그러니까 첫번째 파라미터로 username 과 동일한 데이터를 찾고 두번째 파라미터보다 큰 나이를 가진 데이터를 조회한 것이죠.
즉, 순수 JPA 리포지토리에 작성했던 쿼리가 동일하게 나갑니다.