[Query DSL] 프로젝션과 결과 반환

컴공생의 코딩 일기·2023년 2월 6일
0

Query DSL

목록 보기
3/6
post-thumbnail

프로젝션과 결과 반환- 기본

프로젝션: select 대상 지정

1. 프로젝션 대상이 하나일 때

List<String> result = queryFactory
 .select(member.username)
 .from(member)
 .fetch();
  • 프로젝션 대상이 하나면 타입을 명확하게 지정할 수 있다.

2. 튜플 조회

프로젝션 대상이 둘 이상일 때 사용 (com.querydsl.core.Tuple)

List<Tuple> result = queryFactory
 .select(member.username, member.age)
 .from(member)
 .fetch();
for (Tuple tuple : result) {
 String username = tuple.get(member.username);
 Integer age = tuple.get(member.age);
 System.out.println("username=" + username);
 System.out.println("age=" + age);
}

프로젝션 결과 반환 - DTO 조회

  • MemberDto 클래스
```java
package study.querydsl.dto;
import lombok.Data;
@Data
public class MemberDto {
 private String username;
 private int age;
 public MemberDto() {
 }
 public MemberDto(String username, int age) {
 this.username = username;
 this.age = age;
 }
}

순수 JPA에서 DTO 조회

List<MemberDto> result = em.createQuery(
 "select new study.querydsl.dto.MemberDto(m.username, m.age) " +
 "from Member m", MemberDto.class)
 .getResultList();
  • 순수 JPA에서 DTO를 조회할 때는 new 명령어를 사용해야한다.
  • DTO의 package 이름을 다 적어줘야 하기 때문에 코드가 지저분해진다.
  • 생성자 방식만 지원한다.

Query DSL Dto 조회

  • 프로퍼티 접근
  • 필드 직접 접근
  • 생성자 사용

1. 프로퍼티 접근

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

2. 필드 접근

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

필드 접근 시 변수 명이 다를 때

  • DTO 클래스에 변수 명은 name
  • Entity 클래스에 변수 명은 username
List<UserDto> fetch = queryFactory
 .select(Projections.fields(UserDto.class,
 member.username.as("name"),
 ExpressionUtils.as(
 JPAExpressions
 .select(memberSub.age.max())
 .from(memberSub), "age")
 )
 ).from(member)
 .fetch();
  • ExpressionUtils.as(source,alias) : 필드나, 서브 쿼리에 별칭 적용
  • username.as("memberName") : 필드에 별칭 적용

3. 생성자 접근

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

프로젝션과 결과 반환 - @QueryProjection

생성자 + @QueryProjection

@Data
public class MemberDto {
 private String username;
 private int age;
 public MemberDto() {
 }
 @QueryProjection
 public MemberDto(String username, int age) {
 this.username = username;
 this.age = age;
 }
}
  • build를 실행하면 QMemberDto 클래스가 생성된다.
List<MemberDto> result = queryFactory
 .select(new QMemberDto(member.username, member.age))
 .from(member)
 .fetch();
  • @QueryProjection 방법은 컴파일러로 타입을 체크할 수 있으므로 가장 안전한 방법이다. 하지만 DTOQeuryDSL 어노테이션을 유지해야하는 점과 DTO까지 Q파일은 생성해야하는 단점을 가지고 있다.
profile
더 좋은 개발자가 되기위한 과정

0개의 댓글