[QueryDSL] 엔티티 조회 시에 DTO 로 매핑 하는 방법 2탄 (ObjectList in Object)

반응형

Introduction

예전에 QueryDSL 를 통해 데이터를 조회할 때 바로 DTO 객체로 응답 받는 방법을 포스트(https://mokggang.tistory.com/68) 했었는데.
자식 객체 기준에서의 부모 객체를 조회하는(Object in Object) 것 말고,
부모 객체 기준으로 자식객체를 조회하는(ObjectList in Object) 데이터가 필요한 경우

 

'일대다 관계의 부모와 자식 엔티티를 Join 으로 모두 조회 할 경우에도  DTO 객체로 응답 받아서 사용할 순 없을까 ?'

 

jpaQueryFactory.
    select(
        team.id,
        team.name
        )).
    from(team).
    join(team.memberList, member)
    fetch();

위와 같이 TeamDTO 객체 안에 MemberDTO list 를 가진  DTO로 조회하고 싶었다.

처음엔 그냥 QueryDSL의 어마무시함을 믿고, 예전 포스팅 한 내용 대로 동일한 DTO 변환 함수(Projections)를 사용해도 queryDSL이 타입만 보고 알아서 해주지 않을까? 라는 생각에 시도 해보았지만 에러가 발생할 뿐 이었다.

 

방법

방법을 찾아보니, transform 이라는 함수로 원하는 결과를 얻을 수 있었다. 나는 정확히 Team DTO 하위에 MemberDTO LIST 가 있기를 원했고, 그러한 결과물을 얻을 수 있었다.

jpaQueryFactory.
    select(team).
    from(team).
    join(team.memberList, member).
    transform(GroupBy.groupBy(team.id).as(Projections.bean(TeamDTO.class,
    team.id,
    team.name,
    GroupBy.list(Projections.bean(MemberDTO.class,
            member.name,
            member.age,
            member.address)).as("memberList"))
    )).get(0);

 

GroupBy.groupBy 로 그룹지을 기준을 지정해주고, 데이터를 DTO 로 매핑하며, 매핑 하는 값에 GroupBy.list로 하위 객체를 DTO LIST로 변환 후 상위 DTO 객체의 필드에 매핑해준다. 반환 값은 TeamDTO List 형태로 반환해준다.

 

그러나...

사실상 결과를 보면 FetchJoin 처럼 Join 된 모든 데이터를 가지고와서 지정한 기준으로 데이터를 매핑을 해주는 정도이고, 경우에 따라서 멤버가 엄청나게 많은 팀이라면 너무나도 많은 중복행의 데이터가 발생하기 때문에 DB 리소스 낭비가 더 클 것 같다. 어떻게보면 Select 는 결국 한 번 나간건데. 이게 당연한건데 너무 말도 안되는걸 바란게 아닌가 싶다.

반응형

'개발 > QueryDSL' 카테고리의 다른 글

[QueryDSL] 정렬 (동적 정렬)  (0) 2024.03.05
[QueryDSL] 동적 업데이트  (0) 2024.03.04
[QueryDSL] 동적 검색  (0) 2024.03.04
[QueryDSL] 엔티티 조회 시에 DTO 로 매핑 하는 방법  (0) 2024.02.29