메소드 이름으로 쿼리 생성

메소드 이름을 분석해서 JPQL 쿼리 실행합니다. 예를 들어, 이름과 나이를 기준으로 회원을 조회하려면?

순수 JPA 리포지토리

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);
}

당연히 테스트는 성공합니다. 로직상 아무 문제가 없죠. 단지 코드를 직접 짜야한다는게 문제가 되는겁니다.

스프링 데이터 JPA

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 리포지토리에 작성했던 쿼리가 동일하게 나갑니다.