Spring
[Spring] querydsl - 프로젝션과 결과 반환 방법
퉁그리
2022. 1. 5. 01:18
추천하는 방법에는 크게 두가지가 있다.
- 필드 직접 접근
- @QueryProjection 사용
필드 직접 접근
@Test
public void findDtoByField() throws Exception{
List<MemberDto> result = queryFactory
.select(Projections.fields(MemberDto.class,
member.username,
member.age))
.from(member)
.fetch();
}
필드에 직접 접근하기 때문에 생성자 등이 필요없다.
별칭이 다르거나 새로운 컬럼을 쓸 때도 as등을 이용해 활용 가능하다.
@Data
public class UserDto {
private String name;
private int age;
}
@Test
public void findUserDto() throws Exception{
QMember memberSub = new QMember("memberSub");
List<UserDto> fetch = queryFactory
.select(Projections.fields(UserDto.class,
member.username.as("name"),
ExpressionUtils.as(
JPAExpressions
.select(memberSub.age.max())
.from(memberSub), "age")
)
).from(member)
.fetch();
}
@QueryProjection
@Data
public class MemberDto {
private String username;
private int age;
@QueryProjection
public MemberDto(String username, int age) {
this.username = username;
this.age = age;
}
public MemberDto(Member member) {
this.username = member.getUsername();
this.age = member.getAge();
}
}
생성자에 @QueryProjection을 추가하고, gradle의 compileQuerydsl실행하여 QMemberDto 생성
@Test
public void findDtoByQueryProjection() throws Exception{
List<MemberDto> result = queryFactory
.select(new QMemberDto(member.username, member.age))
.from(member)
.fetch();
}
이 방법은 컴파일러로 타입을 체크할 수 있으므로 가장 안전한 방법이다.
다만 DTO에 QueryDSL 어노테이션을 유지해야 하는 점과 DTO까지 Q파일을 생성해야 하는 단점이 있다.
querydsl에 의존적이기 때문에 깔끔하게 사용하길 원하거나 다른방식을 많이 채용하는 곳에선 쓰기 애매할 수 있다.