Spring/Data JPA

[DataJPA] @Query, 레포지토리에 쿼리를 정의

김긍수 2021. 4. 14. 09:54

메소드명으로 쿼리를 생성하는 방법은 메소드명이 너무 길어질 수 있다는 단점이 있다.

 

지금 소개하는 방법은 복잡한 JPQL을 인터페이스안에 있는 메서드에 바로 적을 수 있고 메서드명은 짧게 할 수 있다.

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

	//레포지토리에서 쿼리 삽입
    @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);
}

또 하나의 장점은 쿼리에 오타가 나면 애플리케이션 로딩시점에서 오류가 발생함을 알려준다.

메서드에 정적쿼리를 작성하는 이름이 없는 NamedQuery이다.

로딩시점에 일단 파싱을 하여 sql을 만들어낸다. sql문을 만들면서 오류가 있는지 확인이 된다.

 

조금 간단하면 메소드명으로 쿼리를 생성하는 방법을 사용하고, 조금 복잡하면 쿼리를 직접 정의해서 사용하여 메소드명을 단순하게 가져간다.

 

동적쿼리는? -> 쿼리DSL 사용!!!

 

 


@Query 값, DTO 조회

엔티티 타입을 조회하는게 아닌, 단순 값과 DTO를 조회하는 방법은 무엇일까?

 

<<단순값 조회>>

public interface MemberRepository extends JpaRepository<Member, Long> {
    //사용자 이름 리스트
    @Query("select m.username from Member m")
    List<String> findUsernameList();
}

<<DTO 조회>>

package study.datajpa.dto;

import lombok.Data;

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

2. @Que

public interface MemberRepository extends JpaRepository<Member, Long> {
    //@Query DTO 조회 - new+패키지명+생성자매핑을 꼭 써줘야한다.
    @Query("select new study.datajpa.MemberDto(m.id, m.username, t.name) from Member m join m.team t")
    List<MemberDto> findMemberDto();
}