-
카테고리
-
세부 분야
백엔드
-
해결 여부
해결됨
Querydsl 조회 시, DTO 필드를 List로 받는 방법을 알고 싶습니다.
24.02.29 01:32 작성 24.02.29 01:37 수정 조회수 351
0
안녕하세요.
Querydsl 학습 중에 궁금한 점이 있어서 질문드립니다.
Projection을 이용해서 조회 데이터를 DTO에 반환 받고 싶습니다.
하지만, DTO 필드에 List 타입이 정의되어 있습니다.
이런 경우에는 어떤식으로 데이터를 조회할 수 있는지 궁금합니다.
또한, 현업에서는 이런 형태의 데이터를 조회하기 위해서 어떤 방식으로 하는지 궁금합니다.
객체 그래프 탐색을 이용한 Lazy 조회 후, 로직에서 조건 필터링 ?
각 조건에 맞는 쿼리 여러번 호출 ?
DTO Projection을 이용한 한방 쿼리 ?
다른 방식 ?
조회 데이터를 반환 받기 위한 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;
// .. 중략
}
감사합니다.
답변을 작성해보세요.
1
답변 1