Querydsl SQLExpressions에 listagg 관련 질문

23.11.02 08:29 작성 23.11.02 08:42 수정 조회수 465

0

안녕하세요, 김영한 님.

Querydsl SQLExpressions에 listagg 관련하여 질문이 있습니다.

 

현재 Projections.constructoer 방식으로 조회한 결과를 Dto로 받고있는데요,

SQLExpressions.listagg(컬럼, ",").withinGroup().orderBy(컬럼).getValue().as("listaggs")

로 select후 Dto에서 String으로 못받는데 String으로 받으려면 어떻게 해야 될까요?

 

방법이 없는걸까요? 이미 같은 질문을 남긴 글이 있는데 미해결 상태라 다시 한번 글 올려 봅니다.

 

이방법을 사용하는 이유는 A 테이블, B 테이블이 있는데 1:N의 관계 입니다)

A테이블 조회시 Response에는 B테이블의 컬럼 하나도 추가로 목록에 보여줘야 하는데

그럴때 B테이블의 해당 컬럼의 값이 다른 데이터가 2개 이상일시 A정보가 2건이 나오게 되서
(페이징 처리시에도 총 카운트와 페이징 처리가 제대로 되지 않습니다.)

한 row로 보여지게 하기 위해 사용하려 Querydsl SQLExpressions에 listagg 사용하려는데,

String으로 받을수가 없더군요...
혹 Querydsl SQLExpressions에 listagg 아니더라도 다른 방법이 있을까요?

답변 1

답변을 작성해보세요.

0

인프런 AI 인턴님의 프로필

인프런 AI 인턴

2023.11.03

안녕하세요 skyghy3342 님, 인프런 AI 인턴이에요.

Querydsl SQLExpressions의 listagg 함수를 사용하여 결과를 String으로 받기 위해서는 Projection이 아닌 QueryResults를 사용해야 합니다. Projections.constructor 방식은 DTO를 생성하여 반환하는 방식이기 때문에 String 타입으로 직접 받을 수 없습니다.

대신 QueryResults를 사용하면 List 타입으로 결과를 받아올 수 있으며, 이를 통해 원하는 필드를 String으로 변환하여 사용하실 수 있습니다.

아래는 예시 코드입니다.

QEntity qEntity = QEntity.entity;
QSubEntity qSubEntity = QSubEntity.subEntity;

List<Tuple> tuples = queryFactory
    .select(qEntity.id, SQLExpressions.listagg(qSubEntity.column, ",").withinGroup().orderBy(qSubEntity.column))
    .from(qEntity)
    .join(qEntity.subEntity, qSubEntity)
    .groupBy(qEntity.id)
    .fetchResults()
    .getResults();

List<YourDto> dtoList = tuples.stream()
    .map(tuple -> {
        Long entityId = tuple.get(qEntity.id);
        String listaggValue = tuple.get(SQLExpressions.listagg(qSubEntity.column, ",").withinGroup().orderBy(qSubEntity.column));
        // 원하는 필드를 String으로 변환하여 DTO에 설정
        return new YourDto(entityId, listaggValue);
    }).collect(Collectors.toList());

위의 코드에서는 QueryFactory와 Entity, SubEntity의 QClass를 사용하여 Querydsl을 구성하고, listagg 함수를 사용하여 원하는 필드를 String으로 변환한 뒤 DTO에 설정하였습니다.

Querydsl SQLExpressions의 listagg 외에도 다른 방법들이 있을 수 있으니 문제에 따라서 적합한 방법을 선택하시면 됩니다. 추가로 질문이 있으시면 언제든지 물어보세요. 감사합니다!