-
Dto로 프로젝션 결과 반환JPA/Querydsl 2023. 8. 13. 14:55
@Test public void findDtoByJPQL() { List<MemberDto> result = em.createQuery("select new study.querydsl.dto.MemberDto(m.username, m.age) from Member m", MemberDto.class) .getResultList(); for (MemberDto memberDto : result) { System.out.println("memberDto = " + memberDto); } }
JPQL을 이용해서 Dto로 결과를 반환하려면 new 명령어를 사용해서 패키지명을 전부 다 입력해줘야지 Dto로 받아올 수 있었다.
Querydsl의 빈 생성
- 프러퍼티 접근
- 필드 직접 접근
- 생성자 사용
1. 프로퍼티 접근
@Test public void findDtoBySetter() { List<MemberDto> result = queryFactory .select(Projections.bean(MemberDto.class, member.username, member.age)) // Projections.bean(Dto 클래스, member.변수, member.변수) .from(member) .fetch(); for (MemberDto memberDto : result) { System.out.println(memberDto); } }
프로퍼티 접근(bean)은 Dto에 있는 setter를 통해서 값이 생성되는 방식이다.
2. 필트 활용 방법
@Test public void findDtoByField() { List<MemberDto> result = queryFactory .select(Projections.fields(MemberDto.class, member.username, member.age)) // Projections.fields(Dto 클래스, member.변수, member.변수) .from(member) .fetch(); for (MemberDto memberDto : result) { System.out.println(memberDto); } }
위에서 bean()을 fileds()로 바꿔준거 말고는 차이가 없는데 위에서는 setter를 이용해서 넣었는데 이번에는 그냥 필드에 주입시키는 것이다.
3. 생성자 사용
@Test public void findDtoByConstructor() { List<MemberDto> result = queryFactory .select(Projections.constructor(MemberDto.class, member.username, member.age)) // Projections.constructor(Dto 클래스, member.변수, member.변수) .from(member) .fetch(); for (MemberDto memberDto : result) { System.out.println(memberDto); } }
construcotr는 생성자를 사용하는 것인데, MemberDto 클래스의 타입과 변수 순서가 일치해야 한다.
4. @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; } }
MemberDto의 생성자에 @QueryProjection을 넣어주면 QMemberDto가 생긴다.
장점
@Test public void findDtoByQueryProjection() { List<MemberDto> result = queryFactory .select(new QMemberDto(member.username, member.age)) .from(member) .fetch(); }
이러한 방식의 장점은 생성자를 만들 때 필요한 것들만 주입할 수 있다는 것이다. new QMemberDto(member.username, member.age, member.key)라고 입력하면 컴파일 에러가 생긴다.
위의 경우에서는 이렇게 입력해도 런타임 에러가 생기는데, @QueryProjection은 컴파일 시점에 잡아준다는 장점이 있다.
단점
하지만 Q파일을 별도로 만들어야한다는 단점이 있고, Dto 계층에서 @QueryProjection을 사용하기 때문에 Dto에서도 querydsl의 기능이 들어가는 아키텍쳐 상 문제가 생긴다는 단점이 있다.
4가지 방식의 장단점을 판단해서 필요한 기능을 사용하면 된다.
'JPA > Querydsl' 카테고리의 다른 글
Querydsl의 수정, 삭제 쿼리 (0) 2023.08.13 Querydsl의 동적 쿼리 (0) 2023.08.13 Querydsl - Case 문 (0) 2023.08.13 Querydsl - 서브 쿼리 (0) 2023.08.13 Querydsl - 조인 (0) 2023.08.13