본문 바로가기
공부/Spring

스프링 데이터 JPA에서 쿼리 메소드 기능을 알아보자

by JERO__ 2022. 8. 25.

 

쿼리 메소드의 3가지 기능

쿼리 메소드는 3가지 기능을 제공한다. 다음과 같다.

  • 메소드 이름으로 쿼리 생성 (중요)
  • 메소드 이름으로 JPA NamedQuery 호출 (실무에서 자주 사용되지 않음)
  • @Query 어노테이션을 사용해서 레포지토리 인터페이스에 쿼리 직접 정의 (중요)

하나씩 살펴보자.

 

1. 메소드 이름으로 쿼리 생성

이름과 나이를 통해 회원을 조회한다면?

1-1. 순수 JPA 레포지토리

1-2. 스프링 데이터 JPA

public interface MemberRepository extends JpaRepository<Member, Long> { 
    List<Member> findByUsernameAndAgeGreaterThan(String username, int age);
}

 

2. JPA NamedQuery

JPA의 NamedQuery를 호출할 수 있다. 하지만 실무에선 많이 쓰이지 않는다고 한다(by 김영한님)

  • 엔티티에 어노테이션을 작성한다
@NamedQuery(
        name = "Member.findByUsername",
        query = "SELECT m FROM Member m WHERE m.username= :username"
)
public class Member {
}
  • 레파지토리에서 호출 한다.

1. 순수 JPA

public List<Member> findByUsername(String username) {
    List<Member> resultList = em.createNamedQuery("Member.findByUsername", Member.class)
            .setParameter("username", username)
            .getResultList();
}

 

2. 데이터 JPA

public interface MemberRepository extends JpaRepository<Member, Long> {
    List<Member> findByUsername(@Param("username") String username);
}

그렇다면 어떤 장점이 있어서 사용할까?

애플리케이션 로딩시점에 오류를 확인한다(정적).

 

 

3. @Query 어노테이션을 사용(정적쿼리)

실무에서 많이 사용되고 강력한 기능이다.

  • NamedQuery의 장점을 가진다(로딩시점에 오류 확인)
  • 레파지토리에 바로 쿼리를 작성할 수 있다.
public interface MemberRepository extends JpaRepository<Member, Long> {

    @Query("select m from Member m where m.username = :username and m.age = :age")
    List<Member> findMember(@Param("username") String username, @Param("age") Long age);
}

 

그렇다면 동적쿼리는 어떻게 사용하는가?

→ 쿼리 dsl을 사용하자!

 

 

[참고] 정적쿼리와 동적쿼리의 차이는 다음과 같다.

  • 정적쿼리: 일반적인 SQL쿼리
  • 동적쿼리: 코드의 실행시점에 SQL 쿼리문이 동적으로 구성되어 실행 (IF문 사용 등)

댓글