스프링데이터 + JPA/QueryDSL

22. @QueryProjection

sdafdq 2023. 12. 1. 10:01

@QueryProjection이라는 것을 사용할 것이다.

 

이것으 사용방법은 정말 간단하다.

Dto의 프로젝션으로 사용하길 원하는 생성자에게

@QueryProjection
public MemberDto(String username, int age) {
    this.username = username;
    this.age = age;
}

이렇게 붙여주면 그만이다.

또 하나 해야할 건, 빌드해 줘야 한다.

Q엔티티 빌드할 때와 마찬가지로 

gradle -> other -> compileQuerydsl 해 주면,

빌드 되면서 생성자 하나 있는 파일이 생긴다.

 

@Generated("com.querydsl.codegen.DefaultProjectionSerializer")
public class QMemberDto extends ConstructorExpression<MemberDto> {

    private static final long serialVersionUID = 1356709634L;

    public QMemberDto(com.querydsl.core.types.Expression<String> username, com.querydsl.core.types.Expression<Integer> age) {
        super(MemberDto.class, new Class<?>[]{String.class, int.class}, username, age);
    }
}

보면 생성자 표현식을 상속받았고,

생성자를 보면 표현식을 인자로 받는다.

 

이거를 이제

@Test
public void findDtoByQueryProjection(){
    List<MemberDto> result = query.select(new QMemberDto(m.username, m.age)).from(m)
            .fetch();

    for (MemberDto memberDto : result) {
        System.out.println("memberDto = " + memberDto);
    }
}

이렇게 정말로 생성자 쓰듯이 사용하면 된다.

QueryDSL이란 표현식의 조합에 의해서 쿼리가 만들어진다.

 

저 QMemberDto라는 것은 생성자 표현식을 상속받았으니, 저것은 표현식이다.

 

 

 

단, 이것도 한계가 있긴 있다.

import com.querydsl.core.annotations.QueryProjection;

@Data
@NoArgsConstructor
public class MemberDto {
    private String username;
    private int age;

    public MemberDto(Member member) {
        username = member.getUsername();;
        age = member.getAge();
    }

    @QueryProjection
    public MemberDto(String username, int age) {
        this.username = username;
        this.age = age;
    }
}

Dto라는 것은 Repository 뿐만 아니라 Service, Controller, 심지어 아예 반환을 저거 자체를 하는 경우도 있는데,

 

Dto가 QueryDSL에 의존하게 된다. 즉, 오염된 것이다. 순수 Dto로 있지 못한다. (엔티티에 의존한 생성자 받는 것 정도는 괜찮은 데....)

 

뭐, 그럼에도 쓰는 모양이다. 그러니까 프로젝트 전체가 QueryDSL과 굉장히 밀접하면 그냥 쓰는 모양이다.

 

아니면 전에 배웠던 

https://qwefdg3.tistory.com/934

이걸 쓰면 된다.

 

 

'스프링데이터 + JPA > QueryDSL' 카테고리의 다른 글

24. 동적쿼리. Where 다중 파라미터  (0) 2023.12.01
23. 동적쿼리. BooleanBuilder 방식  (0) 2023.12.01
21. 프로젝션 Dto  (0) 2023.12.01
20. 프로젝션  (0) 2023.11.30
19. 상수, 문자 더하기  (0) 2023.11.30