프로젝션 대상이 하나면 타입을 명확하게 지정할 수 있다 

대상이 둘 이상이면 튜플이나 dto로 조회해야한다 

 

프로젝션 대상이 둘 이상일 때 튜플과 dto로 반환하는 방법이 있다. 

튜플로 조회하는 방법

List<Tuple> result = queryFactory
        .select(member.username, member.age)
        .from(member)
        .fetch();

dto로 반환하는 방법

1. 순수 JPA에서 DTO 조회하는 방법(비추천)

비추천하는 이유 

new 명령어를 사용하고, dto가 있는 패키지 명을 다 명시해야해서 불편하다

생성자 방식만 지원한다 

List<MemberDto> result = em.createQuery(
        "select new study.querydsl.dto.MemberDto(m.username, m.age) " +
                "from Member m", MemberDto.class)
        .getResultList();

 

2. Querydsl 빈 생성(bean population)

에서 3가지 방법을 지원한다(프로퍼티 접근, 필드 직접 접근, 생성자 사용)

1) 프로퍼티 접근(setter)

Projections.bean(Dto 클래스, 호출할 필드) 형식으로 작성 

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

 

2) 필드 직접 접근

Projections.fields(Dto 클래스, 호출할 필드) 형식으로 작성 

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

프로퍼티나,필드 접근 방식에서 필드 이름이 다를 때(별칭이 다를 때) 해결방안

예시)

1. Member(엔티티)에서는 사용자 필드 이름이 username인데, UserDto에서는 사용자 필드 이름이 name일 때

member.username.as("name")으로 필드에 별칭을 적용한다 

.select(Projections.fields(UserDto,Class,
                member.username.as("name"),

2. 필드나, 서브쿼리에 별칭을 적용할 때는 ExpressionUtils.as(source,alias) 사용 

source: 나이가 가장 많은 회원을 조회하는 서브쿼리 

alias: "age"

ExpressionUtils.as(
        JPAExpressions
        .select(memberSub.age.max())
		.from(memberSUb),"age")

 

-전체 코드 

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();

 

3) 생성자 사용 

Projections.constructor()를 사용한다 

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

+ Recent posts