Yebali

Spring Data JPA의 @Query 애너에티션 본문

Spring

Spring Data JPA의 @Query 애너에티션

예발이 2021. 10. 11. 21:16

@Query란?

@Query 애너테이션은 Repository에서 우리가 직접 쿼리를 작성할 수 있게 해준다.
매소드 이름으로 쿼리를 생성하는 기능은 파라미터 숫자가 늘어나면 이름이 너무 지저분해져서
실무에서는 @Query기능을 자주 사용된다.

 

참고로 @Query를 사용하면 애플리케이션 실행 시점에 문법 오류를 발견 할 수 있다는 큰 장점이 있다.

Entity

@Entity
public class Member {

    @Id @GeneratedValue
    @Column(name = "member_id")
    private Long id;
    
    private String username;
    
    private int age;
}

Repository에 적용

Repotory에서 아래와 같이 @Query 애너테이션을 사용하여 쿼리를 직접 작성 할 수 있다.

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를 사용하여 해결하고, 동적 쿼리는 QueryDSL을 사용하면 된다.

 

DTO로 직접 조회하기

@Query를 사용해여 DTO에 바로 조회하는 방법도 있다.

조회용 DTO

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

    public MemberDto(Long id, String username, String teamName) {
        this.id = id;
        this.username = username;
        this.teamName = teamName;
    }
}

Repository

public interface MemberRepository extends JpaRepository<Member, Long> {
    @Query("select new study.datajpa.dto.MemberDto(m.id, m.username, t.name) " +
           "from Member m join m.team t")
    List<MemberDto> findMemberDto();
}

DTO로 직접 조회 하려면 프로젝트 내 DTO 클래스의 위치를 정확히 명시해주고 'new' 키워드를 사용해야한다.
그리고 조회하는 값과 일치하는 생성자가 필요하다.

 

파라미터 바인딩 방법

@Query 애너테이션에서 파라미터를 바인딩하는 방법은 두가지가 있다.

위치 기반

아래 코드에서 '?0'에는 0번째 파라미터인 'username'의 값이 쿼리에 대입된다.

@Query("select m from Member m where m.username =?0")
Member findMembers(@Param string username);

이름 기반

이름 기반 파라미터 바인딩은 @Param 애너테이션에 파라미터에 'name'이라는 이름을 주고
':name' 으로 @Query안에서 사용한다.

@Query("select m from Member m where m.username =:name")
Member findMembers(@Param("name") string username);

참고로 컬렉션도 파라미터 바인딩이 가능하다.

@Query("select m from Member m where m.username in :names")
List<Member> findByNames(@Param("names") List<String> names);

'Spring' 카테고리의 다른 글

Spring Data JPA의 벌크성 수정 쿼리  (0) 2021.10.11
Spring Data JPA의 반환 타입  (0) 2021.10.11
Spring Data JPA의 Named Query  (0) 2021.10.11
Spring Data JPA의 Query Creation  (0) 2021.10.11
Spring Data JPA를 이용한 CRUD  (0) 2021.10.11