[Querydsl] 중급 문법1
목차
- 프로젝션과 결과 반환
- 기본
- DTO 조회
- distinct
프로젝션과 결과 반환
PROJECTION : SELECT 절에서 어떤 컬럼들을 조회할지 대상을 지정하는 것.
기본
프로젝션 대상이 하나
List<String> result = queryFactory
.select(member.username)
.from(member)
.fetch();
- 프로젝션 대상이 하나면 타입을 명확하게 지정할 수 있음
- 프로젝션 대상이 둘 이상이면 Tuple이나 DTO로 조회
Tuple 조회
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);
(soutv)...
}
DTO 조회
순수 JPA
MemberDto
@Data
@NoArgsConstructor
public class MemberDto {
private String username;
private int age;
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이름을 다 적어줘야해서 지저분함
- 생성자 방식만 지원함
Querydsl 빈 생성
결과를 DTO 반환할 때 사용.
- 프로퍼티 접근
- 필드 직접 접근
- 생성자 사용
프로퍼티 접근 - Setter
List<MemberDto> result = queryFactory
.select(Projections.bean(MemberDto.class,
member.username,
member.age))
.from(member)
.fetch();
필드 직접 접근
List<MemberDto> result = queryFactory
.select(Projections.field(MemberDto.class,
member.username,
member.age))
.from(member)
.fetch();
별칭이 다를 때
@Data
public class UserDto {
private String name;
private int age;
}
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();
- 프로퍼티나, 필드 접근 생성 방식에서 이름이 다를 때 해결 방안
ExpressionUtils.as(source, alias)
: 필드나, 서브 쿼리에 별칭 적용username.as("memberName")
: 필드에 별칭 적용
생성자 사용
List<MemberDto> result = queryFactory
.select(Projections.constructor(MemberDto.class,
member.username,
member.age))
.from(member)
.fetch();
@QueryProjection
생성자 + @QueryProjection
@Data
@NoArgsConstructor
public class MemberDto {
private String username;
private int age;
@QueryProjection
public MemberDto(String username, int age) {
this.username = username;
this.age = age;
}
}
./gradlew compileQuerydsl
QMemberDto
생성 확인
@QueryProjection 활용
List<MemberDto> result = queryFactory
.select(new QMemberDto(member.username, member.age))
.from(member)
.fetch();
이 방법은 컴파일러로 타입을 체크할 수 있으므로 가장 안전한 방법이다.
다만, DTO에 QueryDSL 어노테이션을 유지해야 하는 점과 DTO까지 Q파일을 생성해야 하는 단점이 있다.
distinct
List<String> result = queryFactory
.select(member.username).distinct()
.from(member)
.fetch();
distinct는 JPQL의 distinct와 같다.
<출처 : 인프런 - 실전! Querydsl(김영한)>
댓글남기기