Table of Contents
Projections 의 객체 생성방법 4가지
Projections 사용법에 대해 오해를 불러올 수 있다는 의견이 있어 문서 추가작성합니다.
Projections.bean()
기본 생성자(@NoArgsConstructor) + @Setter 를 이용해 객체를 생성합니다.
직관적이고 이해하기 쉽습니다.
약간의 성능 오버헤드가 있습니다.
@Setter 가 필수이므로, 불변객체가 될 수 없습니다.
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor(access = AccessLevel.PROTECTED)
public class UserGroupByDto {
private String username;
private Long count;
}
public List<UserGroupByDto> groupBy() {
return jpaQueryFactory
.select(
Projections.bean(
UserGroupByDto.class
, user.username
, user.count().as("count")
)
)
.from(user)
.groupBy(user.username)
.orderBy(user.username.asc())
.fetch();
}
Projections.fields()
@Setter 를 사용하지 않고 객체에 데이타를 직접 입력합니다.
기본 생성자(@NoArgsConstructor) 가 필요합니다.
@Getter
@NoArgsConstructor
public class UserGroupByDto {
private String username;
private Long count;
private UserGroupByDto(String username, Long count) {
throw new RuntimeException("Projections 을 이용해 객체 생성할 것");
}
}
public List<UserGroupByDto> groupBy() {
return jpaQueryFactory
.select(
Projections.fields(
UserGroupByDto.class
, user.username
, user.count().as("count")
)
)
.from(user)
.groupBy(user.username)
.orderBy(user.username.asc())
.fetch();
}
Projections.constructor()
생성자를 이용해 객체를 생성합니다.
@AllArgsConstructor 가 필수이고, @Setter 는 필요없습니다.
성능이 좋습니다.
변수명 기반 매칭이 아니라 순서기반 매칭으로 생성자와 순서를 일치시켜야 합니다.
@Getter
@AllArgsConstructor
public class UserGroupByDto {
private String username;
private Long count;
}
List<UserGroupByDto> users = queryFactory
.select(Projections.constructor(UserGroupByDto.class,
user.username,
user.count))
.from(user)
.fetch();
@QueryProjection
@QueryProjection 을 지정해서 DTO 도 QClass 를 생성하도록 하고,
생성된 QClass 를 이용하는 방식입니다.
DTO 도 QClass 를 생성하게 되지만, 컴파일 타임 오류체크를 할 수 있고 성능이 좋습니다.
@QueryProjection
를 사용하므로, Querydsl의 의존성이 필요 없는 레이어에서도 해당 의존성이 필요하게 됩니다.
@Getter
@Setter
@NoArgsConstructor
public class UserGroupByDto {
private String username;
private Long count;
@QueryProjection
public UserGroupByDto(String username, Long count) {
this.username = username;
this.count = count;
}
}
public List<UserGroupByDto> groupBy() {
return jpaQueryFactory
.select(new QUserGroupByDto(
user.username
, user.count().as("count")
)
)
.from(user)
.groupBy(user.username)
.orderBy(user.username.asc())
.fetch();
}