25.04.03 TIL DTO projection

신성훈·2025년 4월 3일
0

TIL

목록 보기
161/162

1. DTO Projection이란?

  • Entity가 아닌 DTO(Data Transfer Object)에 직접 쿼리 결과를 매핑하는 방식이다.
  • API 응답에서 불필요한 필드나 연관 관계로 인해 데이터가 무거워지는 걸 방지할 수 있다.
  • 보안이나 성능 최적화 측면에서도 권장되는 방식이다.

2. DTO Projection 종류

1. JPQL 기반 생성자 Projection

public class MemberDto {
    private String username;
    private int age;

    public MemberDto(String username, int age) {
        this.username = username;
        this.age = age;
    }
}
@Query("SELECT new com.example.dto.MemberDto(m.username, m.age) FROM Member m")
List<MemberDto> findMemberDto();
  • new 키워드를 사용하여 DTO 객체를 직접 생성
  • 패키지 경로까지 정확히 명시해야 한다

2. QueryDSL 기반 Projection

실무에서 많이 사용되는 방식

방법 1. 생성자 기반

public class MemberDto {
    private String username;
    private int age;

    public MemberDto(String username, int age) {
        this.username = username;
        this.age = age;
    }
}
List<MemberDto> result = queryFactory
    .select(Projections.constructor(MemberDto.class, member.username, member.age))
    .from(member)
    .fetch();

방법 2. 필드 기반

public class MemberDto {
    public String username;
    public int age;
}
List<MemberDto> result = queryFactory
    .select(Projections.fields(MemberDto.class, member.username, member.age))
    .from(member)
    .fetch();

방법 3. Getter/Setter 기반

public class MemberDto {
    private String username;
    private int age;

    // getter, setter
}
List<MemberDto> result = queryFactory
    .select(Projections.bean(MemberDto.class, member.username, member.age))
    .from(member)
    .fetch();

3. Entity를 직접 반환하지 않는 이유

  • 엔티티에는 연관 관계, Lazy Loading, 내부 로직 등 불필요한 정보가 많음
  • API 응답에서 예기치 않은 순환 참조나 과도한 데이터 전송 문제 발생 가능
  • DTO는 의도한 데이터만 노출할 수 있어 안정성과 성능 측면에서 이점이 많음

4. 마무리

처음에는 Entity 그대로 반환하는 게 편했지만 프로젝트 규모가 커질수록 유지보수나 응답 최적화를 위해 DTO를 사용하는 게 맞다는 걸 체감하게 된다.
QueryDSL의 Projections는 다양한 스타일로 매핑할 수 있어서 목적에 맞는 방식을 유연하게 선택할 수 있다는 장점이 있다.
앞으로는 API 설계할 때 DTO를 먼저 정의하고 쿼리는 DTO에 맞게 projection하는 방향으로 개발 습관을 들여야겠다.

profile
조급해하지 말고, 흐름을 만들고, 기록하면서 쌓아가자.

0개의 댓글