inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

실전! Querydsl

Querydsl 조회 시, DTO 필드를 List로 받는 방법을 알고 싶습니다.

해결된 질문

1911

Anonymous

작성한 질문수 9

0

안녕하세요.

Querydsl 학습 중에 궁금한 점이 있어서 질문드립니다.

 

Projection을 이용해서 조회 데이터를 DTO에 반환 받고 싶습니다.

하지만, DTO 필드에 List 타입이 정의되어 있습니다.

이런 경우에는 어떤식으로 데이터를 조회할 수 있는지 궁금합니다.

 

또한, 현업에서는 이런 형태의 데이터를 조회하기 위해서 어떤 방식으로 하는지 궁금합니다.

  1. 객체 그래프 탐색을 이용한 Lazy 조회 후, 로직에서 조건 필터링 ?

  2. 각 조건에 맞는 쿼리 여러번 호출 ?

  3. DTO Projection을 이용한 한방 쿼리 ?

  4. 다른 방식 ?

 

조회 데이터를 반환 받기 위한 ProductDto는 다음과 같습니다.

public record ProductDto(
        Long id,
        String name,
        int reviewScore,
        int reviewCount,
        int originalPrice,
        int salesPrice,
        List<String> productImages,
        List<String> productDetailImages
) {

    @QueryProjection
    public ProductDto { }

}

 

데이터를 조회 하고자 하는 의도가 담긴 Querydsl은 다음과 같습니다.

public ProductDto findSellingProductById(Long id) {
        return queryFactory
                .select(new QProductDto(
                        product.id,
                        product.name,
                        product.reviewScore,
                        product.reviewCount,
                        productOption.originalPrice,
                        productOption.salesPrice,
                        productImage.imageUrl,
                        productDetailImage.imageUrl
                ))
                .from(product)
                .leftJoin(product.productOptions, productOption)
                    .on(productOption.isDefault.isTrue(),
                        productOption.isSaleable.isTrue(),
                        productOption.isDeleted.isFalse())
                .leftJoin(product.productImages, productImage)
                    .on(productImage.isDeleted.isFalse())
                .leftJoin(product.productDetailImages, productDetailImage)
                    .on(productDetailImage.isDeleted.isFalse())
                .where(product.id.eq(id))
                .fetchOne();
}

 

Product, ProductOption, ProductImage, ProductDetailImage 엔티티는 다음과 같습니다.

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Product extends BaseDateTimeEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "product_id")
    private Long id;

    @Column(length = 50)
    private String name;

    private int reviewScore;

    private int reviewCount;

    // ... 중략

    @OneToMany(mappedBy = "product", cascade = CascadeType.ALL)
    private List<ProductImage> productImages = new ArrayList<>();

    @OneToMany(mappedBy = "product", cascade = CascadeType.ALL)
    private List<ProductDetailImage> productDetailImages = new ArrayList<>();

    @OneToMany(mappedBy = "product", cascade = CascadeType.ALL)
    private List<ProductOption> productOptions = new ArrayList<>();

    // ... 중략
}

 

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class ProductOption extends BaseDateTimeEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "product_option_id")
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "product_id")
    private Product product;

    @Column(length = 30)
    private String name;

    private int originalPrice;

    private int salesPrice;

    // ... 중략

    private Boolean isDefault;

    private Boolean isSaleable;

    private Boolean isDeleted;

    // ... 중략
}

 

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class ProductImage extends BaseDateTimeEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "product_image_id")
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "product_id")
    private Product product;

    private String imageUrl;

    private Boolean isDeleted;

    // ... 중략
}

 

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class ProductDetailImage extends BaseDateTimeEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "product_detail_image_id")
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "product_id")
    private Product product;

    private String imageUrl;

    private Boolean isDeleted;

    // .. 중략
}

 

감사합니다.

java jpa querydsl

답변 1

1

김영한

안녕하세요. Anonymous님

이 부분은 스프링 부트와 JPA 활용2편 섹션 4에 있는 부분들을 참고해주세요 🙂

감사합니다.

1

Anonymous

이해도 잘 되었고, 도움이 많이 되었습니다.

감사합니다^^

SpringBoot 4.X에서의 Querydsl 설정

0

88

2

querydsl 오픈소스에 대한 질문

0

72

1

예제에서의 카운트 쿼리에서 join문과 where문은 필요없지 않나요?

0

109

1

Querydsl 6.X버전에 대해서 어떻게 생각하시나요?

0

317

2

여러 테이블 조인하여 통계치를 구하고자 할 때 어떤 방법이 더 효율적일까요

1

70

1

fetchResults()는 더이상 권장되지 않는다는데 맞나요?

0

160

1

querydsl sum() 메서드 없어요.

0

159

2

build 디렉터리 생성

0

136

2

자바 ORM 표준 JPA 프로그래밍 - 기본편 듣고 바로 학습해도 괜찮을까요?

0

114

2

현재 Querydsl에서 from절 서브쿼리를 지원하나요?

0

91

1

오타 제보 드립니다.

0

72

2

벌크 연산과 flush, clear

0

76

1

Run As Intellij 로 변경시 Q타입 import 불가

0

88

1

QHello import하기 문제 발생

0

147

2

등록된 함수 보는법(H2Dialect) 질문

0

68

2

5.0부터 Querydsl은 향후 fetchCount() , fetchResult() 를 지원하지 않기로 결정했다고 하는데 이에 맞는 강의

1

196

2

[환경설정 PDF 부트 3.0이후 설명 질문] build.gradle에 compileQuerydsl을 정의하지 않은 상태에서 Gradle->Tasks->other->compileQuerydsl을 클릭하라고 하는 이유가 무엇인가요??

1

200

1

querydsl 설정 문제

0

222

2

quey dsl 설정부분

0

158

2

count 쿼리 관련 질문입니다!

0

75

1

stringtemplate를 이용하여 where절 검색 방법 질문 드립니다.

0

89

1

답변부탁드리겠습니다.

0

89

2

(OrderSpecifier)관련 내용 어디있을가요

0

65

1

중급문법 벌크연산에서

0

81

2