전주호
WebSurf
전주호
전체 방문자
오늘
어제
  • 분류 전체보기 (63)
    • CS (1)
    • 프로그래밍 언어 (3)
      • JAVA (1)
      • Python (2)
    • WEB (35)
      • Spring (21)
      • FastAPI (1)
      • React (4)
    • Git (1)
    • Database (2)
    • Cloud (4)
    • Docker (0)
    • Linux (0)
    • AI (8)
      • ComputerVision (3)
      • CUDA (1)
      • Anaconda (1)
      • NLP (1)
    • ETC (9)
    • Project (0)
      • GolaBlur (0)
    • 알고리즘 문제 풀이 (0)
      • 프로그래머스 (0)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • oauth2
  • http
  • spring
  • springboot
  • 백엔드로드맵
  • 테스트
  • 트러블슈팅
  • AI
  • jwt
  • junit
  • Internet
  • AWS
  • Spring Security
  • MobileFaceSwap
  • websocket
  • PYTHON
  • jpa
  • 문제해결
  • db
  • API
  • S3
  • 백엔드
  • react
  • 스프링
  • web
  • EC2
  • 클라우드
  • 단위테스트
  • cloud
  • conda

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
전주호

WebSurf

WEB/Spring

QueryDsl에서 DTO로 조회할 때 @QueryProjection 사용하기

2024. 12. 18. 21:07
반응형

 

지난 포스트에서 QueryDsl을 사용해서 DTO를 조회할 때 다음과 같이 했습니다.

import static org.프로젝트.account.entity.QAccount.account;
import static org.프로젝트.member.entity.QMember.member;

@RequiredArgsConstructor
public class MemberRepositoryImpl implements MemberRepositoryCustom {

  private final JPAQueryFactory query;

  @Override
  public Optional<MemberProfile> findMemberProfile(Long memberId) {
    return Optional.ofNullable(
        query
            .select(Projections.constructor(
                MemberProfile.class,
                member.profileImageUrl,
                member.nickname,
                account.balance))
            .from(member)
            .join(account).on(account.member.eq(member))
            .where(member.memberId.eq(memberId))
            .fetchOne()
    );
  }
}

 

이 코드는 Projections.constructor() 메서드를 사용하면서 가독성이 다소 아쉬웠습니다.

 

다른 객체들처럼 new 키워드를 사용하면 보다 가독성이 높아지지 않을까 싶었습니다.
이처럼 사용하기 위해서는 해당 DTO 클래스를 Q 클래스로 만들어줄 필요가 있었습니다.

DTO 클래스를 Q 클래스로 만들어줄 어노테이션이 바로 @QueryProjection입니다. 

 

DTO class

import com.querydsl.core.annotations.QueryProjection;

public class MemberProfile {

    privtae String profileImageUrl,
    privtae String nickname,
    privtae Long balance

    public MemberProfile() {
    }

    @QueryProjection
    public MemberProfile(String profileImageUrl, String nickname, Long balance) {
        this.profileImageUrl = profileImageUrl;
        this.nickname = nickname;
        this.balance = balance;
    }
}

위와 같이 생성자에 어노테이션을 걸어주고 컴파일을 하게되면 해당 클래스의 Q 클래스가 생성됩니다.
이렇게 생성된 Q 클래스를 new 생성자로 생성하여 값들을 넣어주면 됩니다.

  @Override
  public Optional<MemberProfile> findMemberProfile(Long memberId) {
    return Optional.ofNullable(
        query
            .select(
                new QMemberProfile(
                    member.profileImageUrl,
                    member.nickname,
                    account.balance))
            .from(member)
            .join(account).on(account.member.eq(member))
            .where(member.memberId.eq(memberId))
            .fetchOne()
    );
  }

이렇게 보니 보다 가독성이 높아졌다는 생각이 듭니다!

 

DTO가 record일 경우 

그렇다면 DTO가 기본 class가 아닌 record로 만들어졌다면 어떻게 해야 할까요?
그 방법은 record의 Compact Constructor를 활용하는 것입니다.

import com.querydsl.core.annotations.QueryProjection;

public record MemberProfile(
    String profileImageUrl,
    String nickname,
    Long balance
) {

  @QueryProjection
  public MemberProfile {
  }

}

이렇게 하면 Q 클래스가 생성되어 class와 동일하게 사용 가능합니다.

반응형
저작자표시 (새창열림)

'WEB > Spring' 카테고리의 다른 글

SpringDataJpa와 QueryDsl 함께 사용하기 (feat. @DataJpaTest)  (1) 2024.12.16
단위 테스트 - Controller (feat. 추가적인 단위 테스트의 방향성)  (0) 2024.08.31
단위 테스트 - Service (feat. 테스트 더블)  (0) 2024.08.28
단위 테스트 - Repository (feat. 테스트 픽스쳐)  (0) 2024.08.27
Service의 메서드들이 중복해서 사용하는 로직을 테스트하기  (0) 2024.08.20
    'WEB/Spring' 카테고리의 다른 글
    • SpringDataJpa와 QueryDsl 함께 사용하기 (feat. @DataJpaTest)
    • 단위 테스트 - Controller (feat. 추가적인 단위 테스트의 방향성)
    • 단위 테스트 - Service (feat. 테스트 더블)
    • 단위 테스트 - Repository (feat. 테스트 픽스쳐)
    전주호
    전주호

    티스토리툴바