Projections 결과 핸들링

QueryDSL에서 Projections은 Entity 전체를 가져오는 것이 아니라, 특정 컬럼을 지정해서 원하는 값을 가져올 수 있다. 즉, Entity 외의 (DTO) 값으로 원하는 데이터만 return 할 수 있다.

Projections 사용법

DTO 클래스와 별칭이 다른 경우에는 필드, 서브 쿼리에 별칭을 사용하거나 필드에 별칭을 적용하면 된다.

적용하지 않으면 컴파일 에러는 발생하지 않지만, null을 반환하게 된다.

  1. ExpressionUtils.as(source, “alias”)

  2. entityFieldName.as(”alias”)

Field 조회에서 예시를 작성하겠다.

public class ExampleDto {
  private String placeName;
}

1. Field 조회

Projections.fields

static QExample.example

public class QueryRepositoryImpl {
   ...
   ...
   public List<Example> findBy..() {
      return jpaQueryFactory.select(
			Projections.fields(
				ExampleDto.class,
				example.placeName)
			.from(example)
			.fetch();
}

// 별칭 적용
public class ExampleDto {
   private String pName;
}

// 1. ExpressionUtils(subquery, alias)
select(
   Projections.fields(
		ExampleDto.class,
		ExpressionUtils.as(
		   JPAExpressions.select(..)
				 .from(example)
				 .where(..)
		 , "alias")
	)
	...

// 2. entityFieldName.as()
select(
   Projections.fields(
	ExampleDto.class,
	example.username.as("pName"))
	...

필드에 직접적으로 값을 입력하기 때문에, 대상이 되는 클래스에 Setter, 기본 생성자가 없어도 동작한다.

2. 생성자 조회

Projections.constructor

생성자의 인자에 값을 넘길 때, 순서가 동일해야 한다. 하지만 필드명이 동일하지 않아도 된다.

3. Property(Setter) 조회

Projections.bean

setter(bean)를 통해서 데이터를 인젝션 하기 때문에 기본 생성자가 필요하다.

직접 생성자를 만들거나, @NoArgsContructor 어노테이션을 사용하면 된다.

단일 프로젝션, 다중 프로젝션

단일 프로젝션

다중 프로젝션

튜플의 경우 QueryDSL의 package com.querydsl.core에 종속된다.

프로젝트 적용

적용 전

아래와 같이 Projections를 사용하지 않는다면 Tuple을 다시 return 하려는 값으로 변환해야한다.

적용 후

적용 전과 비교하면 Tuple을 사용했을 때 보다 간단하다고 느낄 수 있다.

복잡한 Join Query 결과에서 특정 데이터만 추출할 때 효율적으로 활용해서 효율적으로 데이터 추출이 가능하고 다양한 데이터를 처리할 때, DTO를 사용해서 타입 안전성을 유지할 수 있다고 생각한다.

Last updated