Skip to content

queryDsl Dto 생성 방법  #3

Open
@suna-ji

Description

@suna-ji

QueryProjection vs Projections.constructor vs Projections.fields 비교 정리

Querydsl에서 DTO를 생성하는 세 가지 방법, QueryProjection, Projections.constructor, Projections.fields의 특징과 차이점을 비교하여 정리합니다.


1. QueryProjection

@QueryProjection 애노테이션을 사용하여 DTO 클래스에 대해 Querydsl의 Q클래스를 생성하고, 이를 통해 DTO 객체를 생성하는 방식입니다. 생성된 QDto 클래스를 사용하여 데이터를 매핑합니다.

특징

  • 타입 체크: 컴파일 타임에 필드 타입과 개수를 체크.
  • Querydsl 의존성: DTO가 Querydsl에 종속됩니다.
  • 설정 복잡도: APT 플러그인을 통한 코드 생성 필요.

장점

  • 컴파일 시 타입 안정성을 제공합니다.
  • DTO 필드 변경 시 컴파일러가 오류를 감지합니다.

단점

  • Querydsl 의존성 때문에 DTO가 독립적으로 사용하기 어렵습니다.
  • APT 설정이 필요합니다.

코드 예제

@Data
@QueryProjection
public class MyDto {
    private String name;
    private int age;
}

List<MyDto> result = queryFactory
    .select(new QMyDto(member.name, member.age))
    .from(member)
    .fetch();

2. Projections.constructor

DTO의 생성자를 호출하여 데이터를 매핑하는 방식입니다.

특징

  • 타입 체크: 런타임에 타입과 필드 개수를 확인합니다.
  • Querydsl 독립성: DTO는 Querydsl에 종속되지 않습니다.
  • 설정 복잡도: 별도 설정이 필요하지 않습니다.

장점

Querydsl에 종속되지 않아 재사용성이 높습니다.
설정이 간단하며 순수 POJO 설계가 가능합니다.

단점

필드 개수나 타입이 맞지 않을 경우 런타임 오류가 발생할 수 있습니다.
생성자 매핑이 복잡해질 수 있습니다.

코드 예제

public class MyDto {
    private String name;
    private int age;

    public MyDto(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

List<MyDto> result = queryFactory
    .select(Projections.constructor(MyDto.class, member.name, member.age))
    .from(member)
    .fetch();

3. Projections.fields

DTO의 필드 이름을 기준으로 데이터를 매핑하는 방식입니다.

특징

  • 타입 체크: 런타임에 필드 이름과 타입을 확인합니다.
  • Querydsl 독립성: DTO는 Querydsl에 종속되지 않습니다.
  • 필드 이름 기반 매핑: 필드 이름이 동일해야 자동으로 매핑됩니다.

장점

Querydsl 의존성이 없으며, 필드 이름이 같을 경우 간단히 매핑할 수 있습니다.
일부 필드만 매핑할 수 있습니다.

단점

DTO에 기본 생성자와 Setter가 필요합니다.
필드 이름이 다를 경우 명시적으로 매핑해야 합니다.

코드 예제

public class MyDto {
    private String name;
    private int age;

    public MyDto() {}

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

List<MyDto> result = queryFactory
    .select(Projections.fields(MyDto.class, member.name.as("name"), member.age.as("age")))
    .from(member)
    .fetch();

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions