스프링/JPA

[Spring Data JPA] NamedQuery 사용하기

imcoding 2022. 9. 19. 20:47

 

NamedQuery

 

 

 

Spring Data Jpa는 기본적으로 findAll, saveAll과 같이 CRUD를 포함한 기본적인 공통 메서드를 인터페이스로 제공한다.

 

그런데 만약, 단순히 전체 값을 조회하거나 키 값을 기준으로 조회하는 것 외에 특성 조건에 따른 값을 조회하고자 한다면 어떻게 해야할까?

 

물론 엔티티 매니저가 제공하는 createQuery 메서드를 사용해 JPQL문으로 DB에서 값을 조회할 수 있다.

 

하지만 만약 JPQL문의 컬럼명이 잘못 되었어도 해당 메서드를 호출하기 전에는 에러가 발생하지 않아 알아차리기 힘들다.

 

메서드 이름으로 쿼리를 생성해주기도 하지만, 조건이 많아질수록 메서드 이름이 길어진다는 단점이 있다.

(findByAgeLessThan, findByUserNameAndAgeGreaterThan 등)

 

NamedQuery는 이 문제를 해결하면서 우리가 원하는 값을 가져올 수 있다.

@Entity
@NamedQuery(
        name="Member.findByUsername",
        query="select m from Member m where m.userName = :userName"
)
public class Member {

    @Id
    @GeneratedValue
    private Long id;

    private String userName;
}

사용법이다.

 

우리가 접근하길 원하는 엔티티에 가서 @NamedQuery를 사용한다.

해당 NamedQuery를 호출할 때 사용할 이름을 "name"으로 정의하고, JPQL문을 "query"로 작성한다.

 

 

public interface MemberRepository extends JpaRepository<Member, Long> {
    @Query(name = "Member.findByUsername")
    List<Member> findByUserName(@Param("userName") String userName);
}

그리고 우리가 만든 레파지토리에 가서 위에서 만든 NamedQuery를 사용해 메서드를 만들 수 있다.

 

@Query를 선언하고 name에는 위에서 정한 name을 넣는다.

 

그리고 NamedQuery에서 만든 JPQL에 파라미터 값이 있다면 해당 값을 @Param으로 작성해서 변수명과 바인딩 해준다.

 

추가로, @Query 어노테이션은 생략 가능하다.

 

우리가 작성한 findByUserName 메서드 명을 보고 해당 엔티티에서 NamedQuery를 찾아오기 때문이다.

 

먼저 NamedQuery의 유무 부터 찾고, 만약 해당하는 쿼리가 없다면 그 때 가서 메서드 이름으로 쿼리를 생성하기 때문에 생략 가능하다.

 

NamedQuery는 에러 파악이 수월하다는 점이 가장 큰 장점이다.

 

JPQL의 문법에 오류가 있어도 해당 메서드를 실행하기 전에는 에러가 발생하지 않는 createQuery와 달리,

NamedQuery는 어플리케이션 동작 시점에 문법 오류가 있다면 원인과 함께 즉시 에러가 발생하기 때문이다.

 

 

사실, NamedQuery 를 이용한 쿼리문 작성은 실무에서는 그다지 많이 쓰이지 않는다.

 

최대한 깔끔한 엔티티 형태를 유지하고자 하는 취지에 맞지 않기 때문이다.

 

그래서 다음 시간에는 엔티티에 NamedQuery 선언 없이 레파지토리에 직접 JPQL을 작성하여 메서드를 만들어보겠다.

https://imcoding.tistory.com/61

 

[Spring Data JPA] @NamedQuery 없이 레파지토리에 직접 쿼리 작성하기

지난번 엔티티에 @NamedQuery를 이용해 JPQL을 작성 후 값을 조회하는 방법을 알아보았다. https://imcoding.tistory.com/60 [Spring Data JPA] NamedQuery 사용하기 NamedQuery Spring Data Jpa는 기본적으로 fin..

imcoding.tistory.com