반응형
프로젝션
QueryDSL에서 프로젝션을 사용하는 방법을 알아보자.
프로젝션
: select 절에 조회 대상을 지정하는 것 ex) Dto로 조회
기본
List<String> result = queryFactory
.select(member.username)
.from(member)
.fetch();
- 프로젝션: select 대상 지정
- 프로젝션 대상이 하나면 리턴되는 타입이 해당 타입으로 반환된다.
튜플 조회
List<Tuple> result = queryFactory
.select(member.username, member.age)
.from(member)
.fetch();
- 여러 컬럼을 조회할 때에는
com.mysema.query.Tuple
타입을 사용해서 반환된다. - 조회 결과는
result.get(member.username)
과 같은 형태로 받아온다.
DTO 조회
Dto를 이용해 조회하는 경우는 프로퍼티 접근
, 필드 직접 접근
, 생성자 사용 방식
이 있다.
프로퍼티 접근
List<MemberDto> result = queryFactory
.select(Projections.bean(MemberDto.class, member.username, member.age))
.from(member)
.fetch();
- 프로퍼티 접근 방식은
Projections.bean(dto클래스, 파라미터...)
을 이용한다. - 내부적으로
new DTO()하여 객체를 생성
하고,setter메서드
를 이용해 필드를 넣어준다. - 때문에
기본 생성자
와setter메서드
가 꼭 필요하다.
필드 직접 접근
List<MemberDto> result = queryFactory
.select(Projections.fields(MemberDto.class, member.username, member.age))
.from(member)
.fetch();
- 필드 직접 접근 방식은
Projection.fields(dto클래스, 파라미터...)
을 이용한다. - 프로퍼티 접근 방식과 다르게 내부적으로 객체를 생성하면서 파라미터를 바로 넣어주기 때문에
setter메서드
가 필요하지 않다. - 필드를
private
로 설정해도 동작한다.
생성자 사용
List<MemberDto> result = queryFactory
.select(Projections.constructor(MemberDto.class, member.username, member.age))
.from(member)
.fetch();
- 생성자 사용 방식은
Projections.constructor(dto클래스, 파라미터...)
을 이용하며, 말 그대로 생성자를 이용한다. - 생성자를 사용하기 때문에 파라미터를 받아줄 생성자가 필요하며, 파라미터 순서도 생성자의 파라미터 순서와 일치해야 한다.
alias 사용 시 - 프로퍼티 접근, 필드 직접 접근
QMember memberSub = new QMember("memberSub");
List<UserDto> result = queryFactory
.select(Projections.fields(UserDto.class,
member.username.as("name"),
ExpressionUtils.as(
JPAExpressions
.select(memberSub.age.max())
.from(memberSub)
, "age"
)
))
.from(member)
.fetch();
- 프로퍼티 접근 방식이나 필드 직접 접근 방식일 때에는 필드명과 컬럼명을 일치시켜주어야 한다.
- dto의 필드명이 엔티티 필드명과 다를 때에는 alias를 사용해야한다.
member.username.as("name")
와 같이 필드에 직접 alias를 설정한다.- 필드나 서브쿼리에 별칭을 사용하는
ExpressionUtils.as(source, alias)
를 이용하기도 한다.
@QueryProjection
@QueryProjection
public MemberDto(String username, int age) {
this.username = username;
this.age = age;
}
...
List<MemberDto> result = queryFactory
.select(new QMemberDto(member.username, member.age))
.from(member)
.fetch();
- dto클래스를 QType로 생성해 사용하는 방식이다.
- 컴파일 시점에서 에러를 잡아낼 수 있다는 강력한 장점이 있다.
- 하지만 QType을 생성해야 하는 단점이 있는데
이는 DTO클래스 내부에 QueryDSL 어노테이션이 포함되어 의존하는 문제가 생긴다.
반응형
'Java & Kotlin > Spring Data' 카테고리의 다른 글
[QueryDSL] Spring Data JPA와 QueryDSL 사용하기 (0) | 2022.05.15 |
---|---|
[QueryDSL] 벌크연산과 SQL Funtion (0) | 2022.05.15 |
[QueryDSL] 동적쿼리 (0) | 2022.05.14 |
[QueryDSL] QueryDSL 기본문법 (0) | 2022.05.11 |
[QueryDSL] QueryDSL 시작하기 (0) | 2022.05.10 |
[JPA] UniqueConstraint와 Embedded field (0) | 2022.05.07 |