Query DSL로 Group By 처리를 수행하여 집계 연산 결과를 받아오는 테스트를 수행해보자.

아래 예제는 여러건의 집계 결과를 리스트로 받아오는 테스트이다.

우선 StatusSummary라는 결과를 담아올 객체를 생성한다.

StatusSummary.java

@Data
@AllArgsConstructor(access = AccessLevel.PUBLIC)
public class StatusSummary {

    @NotNull
    private Long id;

    @NotNull
    private Long statusCode;

    @NotNull
    private Integer counts;
}

결과를 받아오는 쿼리 DSL구문

QUserStatus table = QUserStatus.userStatus;

JPAQuery query = new JPAQuery(entityManager);

// 뽑은 결과를 StatusSummay에 담을 것이기 때문에 표현식을 생성한다. 
ConstructorExpression<StatusSummary> constructor = Projections.constructor(StatusSummary.class, table.id, table.statusCode, Wildcard.countAsInt);

List<CSReturnStatusSummary> list = query.from(table)
        .where(table.id.in(ids)
            .and(table.status.in("AAA", "BBB")))
        .groupBy(table.id, table.status)  // groupBy를 수행할 필드 나열
        .list(constructor);

그룹 키를 이용하여 Map 형태로 받아오기.

transform을 이용하면 다양한 형태의 자료구조로 변환이 가능하다.

import static com.querydsl.core.group.GroupBy.*;

Map<Integer, List<Comment>> results = query.from(post, comment)
    .where(comment.post.id.eq(post.id))
    .transform(groupBy(post.id).as(list(comment)));

복수개의 칼럼이 존대한다면 다음과 같이 Group로 담아낸다.

이를 이용하여 postID를 키로하고, 값은 Group가 되며 내부에는 post.name과 comment.id의 셋으로 접근이 가능하다.

Map<Integer, Group> results = query.from(post, comment)
    .where(comment.post.id.eq(post.id))
    .transform(groupBy(post.id).as(post.name, set(comment.id)));