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