이번 포스팅해서 기본 문법보다 조금 어려운 문법을 다룰 예정이라서 기본 문법은 아래 링크를 참조해주세요
https://pjstudyblog.tistory.com/110
DTO 반환 방법
1. 프로퍼티 접근 - Projections.bean()
List<MemberDto> result = queryFactory
.select(Projections.constructor(MemberDto.class, member.username, member.age))
.from(member)
.fetch();
Projections.bean()는 setter 프로퍼티가 있으면 setter를 통해서 접근을 하고 setter가 없다면 리플렉션으로 접근합니다.
2. 필드 접근 - Projections.fields()
List<MemberDto> result = queryFactory
.select(Projections.fields(MemberDto.class,
member.username,
member.age))
.from(member)
.fetch();
엔티티에 있는 필드명과 DTO에 있는 필드는 동일해야 하며, 이름이 다른 경우에는 as() 메소드를 사용하여 DTO에 원하는 필드명을 입력해주면 됩니다.
3. 사용자 사용 - Projections.constructor
List<MemberDto> result = queryFactory
.select(Projections.constructor(MemberDto.class,
member.username,
member.age))
.from(member)
.fetch();
}
생성자를 통해서 값을 설정 단 DTO에 있는 필드 타입과 엔티티에 있는 타입이 동일해야 합니다
그럼 DTO를 반환할 때 서브쿼리를 어떻게 써야 될까요?? 서브쿼리의 명칭을 정해 DTO에 필드를 생성할 수 없기 때문에 ExpressionUtils를 이용해 이 문제를 해결할 수 있으며, ExpressionUtils는 DTO를 반환하는 QueryDSL에서 서브쿼리에 명칭을 지정할 수 있도록 도와주는 클래스입니다.
@Test
public void dtoByExpressionUtils() {
QMember subQuery = new QMember("subQuery");
List<MemberDto> fetch = queryFactory
.select(Projections.fields(MemberDto.class,
member.username.as("name"),
ExpressionUtils.as(
JPAExpressions
.select(subQuery.age.max())
.from(subQuery), "age")))
.from(member)
.fetch();
}
4. @QueryProjection
@Test
public void dtoByQueryProjection() {
List<MemberDto> result = queryFactory
.select(
new QMemberDto(member.username, member.age))
.from(member)
.fetch();
}
@QueryProjection은 constructor()와 유사하다고 생각할 수 있지만 컴파일 시점에서 오류를 잡을 수 있는 반면, constructor()는 런타임에서 오류를 발견하게 됩니다. 그러나 @QueryProjection을 사용하면 순수한 DTO 클래스가 QueryDSL에 의존하게 되는 단점이 있어 DTO가 controller, service, repository 등 여러 계층에서 사용될 경우 다른 계층도 QueryDSL에 의존하게 되는 문제가 발생합니다.
참고자료
https://jojoldu.tistory.com/379
[Querydsl] 서브쿼리 사용하기
안녕하세요! 이번 시간에는 Querydsl에서의 Subquery 기본 가이드를 진행합니다. 개인적으로 ORM을 사용하며, 객체지향적으로 엔티티가 구성되어있으면 서브쿼리가 필요한 일은 거의 없다고 생각하
jojoldu.tistory.com
https://jong-bae.tistory.com/63
[QueryDSL] Projections, @QueryProjection 을 사용하여 DTO로 반환하기
엔티티가 연관관계없이 특정 컬럼들만 조인해서 뽑아와야 할때가 있다. 이때 엔티티에 값을 담아서 리턴할 수 없어서 DTO에 반환해야 하는데 Projections 를 이용하면 보기좋게 코드를 작성할 수 있
jong-bae.tistory.com
https://green-bin.tistory.com/24
JPA - Querydsl를 사용해 DTO 받는 방법
프로젝트를 진행하면서 조회한 도메인을 Mapstruct 라이브러리를 사용해 DTO로 매핑했었다. 하지만 점점 비즈니스 로직이 복잡해면서 매핑을 위한 코드도 같이 복잡해지다보니 도메인을 거치지
green-bin.tistory.com
'JAVA > JPA' 카테고리의 다른 글
[QueryDSL] fetchResults(), fetchCount() 대안 - QeuryDSL 5.0.0 버전 이후 (1) | 2025.02.05 |
---|---|
[QueryDSL] QueryDSL 문법 #4 - 동적 쿼리 (0) | 2025.02.02 |
[QueryDSL] Spring Data JPA + QueryDSL 기본 문법 #2 - from절에 서브쿼리 사용 문제 해결 (0) | 2025.01.30 |
[QueryDSL] Spring Data JPA + QueryDSL 설정 #1 (1) | 2025.01.22 |
[JPA] OSIV(Open Session In View) 패턴 이해 (2) | 2024.12.16 |