1. 프로젝션에 대상 개수에 따른 결과
프로젝션은 SELECT 대상 지정이다.
1-1. 대상이 하나일 때
- 타입을 명확하게 지정할 수 있다.
1-2. 대상이 둘 이상
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로 반환하자
2. DTO를 통해 조회해보자
2-1. JPA에서 DTO로 조회해보자(비교)
List<MemberDto> result = em.createQuery(
"select new study.querydsl.dto.MemberDto(m.username, m.age) " +
"from Member m", MemberDto.class)
.getResultList();
- DTO의 package 이름을 다 적어주기 때문이 지저분하다.
- 생성자 방식만 지원한다.
2-2. Querydsl에서 DTO로 조회해보자
접근 방법에 3가지 방법이 있다.
- 프로퍼티 접근
- 필드 직접 접근
- 생성자 사용
하나씩 살펴보자!
프로퍼티 접근 (Setter)
List<MemberDto> result = queryFactory
.select(Projections.bean(MemberDto.class,
member.username,
member.age))
.from(member)
.fetch();
필드 직접 접근
List<MemberDto> result = queryFactory
.select(Projections.fields(MemberDto.class,
member.username,
member.age))
.from(member)
.fetch();
엔티티 네임과 DTO 네임(별칭)이 다르다면, 별칭으로 변환해주어야 한다.
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();
- as : 필드에 별칭 적용
- ExpressionUtils.as(source,alias) : 필드나, 서브 쿼리에 별칭 적용
생성자 사용
List<MemberDto> result = queryFactory
.select(Projections.constructor(MemberDto.class,
member.username,
member.age))
.from(member)
.fetch();
}
3. @QueryProjection을 통해 DTO를 select대상으로 바로 설정해보자
DTO 생성자에 @QueryProjection 어노테이션을 추가해보자
- ./gradlew compileQuerydsl
- QMemberDto가 생성된다
@QueryProjection
public MemberDto(String username, int age) {
this.username = username;
this.age = age;
}
select 절에서 해당 DTO를 바로 사용할 수 있다.
List<MemberDto> result = queryFactory
.select(new QMemberDto(member.username, member.age))
.from(member)
.fetch();
- 컴파일러로 타입을 체크할 수 있으므로 가장 안전한 방법이다.
- 하지만, DTO에 QueryDSL 어노테이션을 유지해야 하며 DTO까지 Q파일을 생성한다.
- DTO가 QueryDSL의 의존성을 가진다.
- 팀 컨밴션으로 정해서 사용하자
4. distinct
JPQL의 distinct와 같다.
List<String> result = queryFactory
.select(member.username).distinct()
.from(member)
.fetch();
'공부 > Spring' 카테고리의 다른 글
QueryDSL에서 수정, 삭제 벌크연산 하는방법을 알아보자 (0) | 2022.08.26 |
---|---|
[QueryDSL] 동적쿼리를 해결해보자 (0) | 2022.08.26 |
[QueryDSL] 기본 문법을 알아보자 (0) | 2022.08.26 |
QueryDSL을 적용해보자 (0) | 2022.08.26 |
스프링 데이터 JPA에서 Auditing을 적용해보자! (0) | 2022.08.25 |
댓글