📝프로젝션 대상이 둘 이상
- 프로젝션 대상이 하나인 경우 타입을 명확하게 지정 가능합니다.
- 그러나 프로젝션 대상이 둘 이상인 경우에는 타입을 DTO나 Tuple로 지정해야 합니다.
- DTO로 조회하는 법을 설명드립니다.
📝순수 JPA에서 DTO 조회
- 쇼핑몰 프로젝트 진행 중에 순수 JPA에서 DTO를 조회하는 방법을 사용하였습니다.
- DTO 조회
1. Setter - (프로퍼티) 접근으로 DTO 조회
public void findDtoBySetter() {
List<MemberDto> result = queryFactory
.select(Projections.bean(MemberDto.class,
member.username,
member.age))
.from(member)
.fetch();
}
2. 필드 직접 접근
public void findDtoByField() {
List<MemberDto> result = queryFactory
.select(Projections.fields(MemberDto.class,
member.username,
member.age))
.from(member)
.fetch();
}
3. 생성자 접근
@Test
public void findDtoByConstructor() {
List<MemberDto> result = queryFactory
.select(Projections.constructor(MemberDto.class,
member.username,
member.age))
.from(member)
.fetch();
}
4. @QueryProjection 이용 접근
public void findDtoByQueryProjection() {
List<MemberDto> result = queryFactory
.select(new QMemberDto(member.username, member.age))
.from(member)
.fetch();
}
@Data
@NoArgsConstructor
public class MemberDto {
private String username;
private int age;
@QueryProjection
public MemberDto(String username, int age) {
this.username = username;
this.age = age;
}
}
📝3, 4번 방법 장, 단점
- 3번과 4번은 둘 다 생성자를 사용한 방법으로서 객체 생성 시점에 값들을 한 번에 할당하기 때문에, 객체의 불변성을 유지하는 장점이 있습니다.
- 생성자의 인자가 잘못된 경우에 3번 방법의 경우 최악의 오류인 Runtime 오류가 발생하게 됩니다.
- 반면 4번 방법의 경우 Compile 오류가 발생합니다. Compile 시점에 오류가 발생하는 것이 가장 안전한 방법입니다.
- 4번 방법이 제일인것 같지만 DTO(MemberDto)에 @QueryProjection 어노테이션을 사용함으로써 DTO가 QueryDSl에 대한 의존성을 가지게 된다는 단점이 있습니다.
- 실무에서 사용할 경우 회사에서 지향하는 스타일을 사용하는 것이 현명하다고 생각합니다.