지난번 엔티티에 @NamedQuery를 이용해 JPQL을 작성 후 값을 조회하는 방법을 알아보았다.

https://imcoding.tistory.com/60

 

[Spring Data JPA] NamedQuery 사용하기

NamedQuery Spring Data Jpa는 기본적으로 findAll, saveAll과 같이 CRUD를 포함한 기본적인 공통 메서드를 인터페이스로 제공한다. 그런데 만약, 단순히 전체 값을 조회하거나 키 값을 기준으로 조회하는 것

imcoding.tistory.com

 

 

하지만 실제로 위 방법은 실무에서 많이 쓰이지 않는다.

 

엔티티에 쿼리문을 작성하는 방식 자체가 속성값만을 유일하게 갖는 게 베스트인 엔티티 취지에 맞지 않기 때문이다.

 

오히려 쿼리문은 레파지토리에 직접 작성하는 게 더 어울리기도 하고 말이다.

 

방법이 매우 간단하니 바로 코드를 보며 설명하겠다.

@Entity
public class Member {

    @Id
    @GeneratedValue
    private Long id;

    private String userName;
}

우선, 엔티티에 NamedQuery를 따로 선언하지 않고 깔끔한 모습을 유지했다.

 

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") int age);
}

그리고 레파지토리로 와서 @Query를 선언 후 JPQL을 작성한다.

 

@Query 어노테이션이 생략 가능했던 NamedQuery 방식과는 다르게 여기서는 필수로 들어가야 한다.

 

메서드는 NamedQuery 방식과 동일하게 @Param으로 파라미터값이 되는 변수를 바인딩 해주면 된다.

 

엔티티에 있는 NamedQuery를 없애고, 해당 부분에 있던 JPQL을 레파지토리로 가져와서 @Query 어노테이션 안에 넣어준다고 생각하면 된다.

(NamedQuery에서는 @Query 안에 쿼리 이름을 정해줬으나, 이 방식에서는 쿼리 이름을 따로 정하지 않는다.)

 

 

 

물론 엔티티가 갖는 특정 속성만 가져오도록 JPQL을 작성할 수도 있다.

public interface MemberRepository extends JpaRepository<Member, Long>
    @Query("select m.userName from Member m")
    List<String> findUsernameList();
}

Member 객체가 갖는 userName 필드값만 가져오도록 작성해보았다.

 

 

엔티티 값을 Dto로 변환해서 가져오고자 할때는 이와 같이 하면 된다.

package practice.study.dto;


@Data
public class MemberDto {
    private Long id;
    private String name;
    private String teamName;

    public MemberDto(Long id, String name, String teamName) {
        this.id = id;
        this.name = name;
        this.teamName = teamName;
    }
}
public interface MemberRepository extends JpaRepository<Member, Long> {
    @Query("select new practice.study.dto.MemberDto(m.id, m.userName, t.name) from Member m join m.team t")
    List<MemberDto> findMemberDto();
}

특이한 부분은 select 부분을 new 경로(엔티티 속성) 으로 받았다는 부분이다.

(Member : Team = N : 1 다대일 매핑)

 

추가로, 이 방법 또한 JPQL에 문법 오류가 있을 경우 어플리케이션 실행 시 해당 메서드 호출 여부와 상관 없이 문법 오류로 인한 에러를 발생시켜 잘못된 부분을 파악하기 쉽다는 장점이 있다

(NamedQuery 방식도 동일)

 

createQuery를 이용한 JQPL 작성은 문법 오류가 있어도 해당 메서드를 호출하기 전에는 에러가 발생하지 않기 때문에 그것과는 큰 차별점으로 볼 수 있다.

 

따라서 NamedQuery 방식을 먼저 알고, 오늘 소개한 방식을 더 중점적으로 이해하는 것을 권장드린다.

(깔끔한 엔티티 클래스를 선호하는 실무 특성상 이 방법이 더 많이 쓰이기 때문)

 

 

 

 

 

 

복사했습니다!