DOing
[Querydsl] 튜플이나 DTO로 결과 반환하기 본문
프로젝션 : select 대상지정하는 일
프로젝션 대상이 두개 이상이라면 튜플이나 DTO로 조회해야한다.
🌱 튜플 사용하기
com.querydsl.core.Tuple를 사용하고 있다.
때문에 Repository 계층을 넘어서 Service나 Controller계층에 넘어가는 것은 좋지않은 설계다.
Service나 Controller계층에 넘어갈때는 DTO로 넘어가는 것이 좋다고 생각한다.
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 사용하기
DTO를 사용하려면 다음 3가지 방법 지원한다.
- 프로퍼티 접근
- 필드 직접 접근
- 생성자 사용
1. Bean() -> getter, setter, 디폴트 생성자 필요
List<MemberDto> result = queryFactory
.select(Projections.bean(MemberDto.class,
member.username,
member.age))
.from(member)
.fetch();
2. 필드 직접 접근 -> getter, setter필요없음. 바로주입
List<MemberDto> result = queryFactory
.select(Projections.fields(MemberDto.class,
member.username,
member.age))
.from(member)
.fetch();
3. 생성자 사용
List<MemberDto> result = queryFactory
.select(Projections.constructor(MemberDto.class,
member.username,
member.age))
.from(member)
.fetch();
번외 ) DTO의 이름이 다르다면?
ExpressionUtils.as(source,alias)-> 필드나, 서브 쿼리에 별칭 적용
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();
4. @QueryProjection
DTO 생성자에 @QueryProjection을 붙여주면 DTO도 Q파일로 생성된다.
import com.querydsl.core.annotations.QueryProjection;
public class MemberDto {
private String username;
private int age;
public MemberDto() {
}
@QueryProjection
public MemberDto(String username, int age) {
this.username = username;
this.age = age;
}
}
생성된 Q파일을 사용하면된다.
queryFactory
.select(new QMemberDto(member.username, member.age))
.from(member)
.fetch();
-> 이 방법의 좋은점은 컴파일오류로 많은 것을 잡아낼 수 있다는 것이다.
-> 컴파일 시점에 타입 체크, 파라미터 갯수체크 등 가능하다.
-> 단, memberDto가 Querydsl에 대한 의존성이 생긴다는 단점이 있다.
특히 DTO는 Service계층, Controller계층등 여러 계층을 넘어다니는 객체임으로 아키텍쳐 전반적으로 Querydsl에 대한 의존성이 생기는 것이 큰 단점이 생길 수 있다.
'JPA' 카테고리의 다른 글
[JPA] JPQL이란? (0) | 2021.08.08 |
---|---|
[JPA] Fetch Join (1) | 2021.08.06 |
[Querydsl] 서브쿼리 (0) | 2021.08.04 |
[Querydsl] Join (0) | 2021.08.04 |
[Querydsl] 정렬, 페이징, 집계 함수, 그룹 함수 (0) | 2021.08.04 |