Order와 OrderItem, Item을 join해서 한번에 다 가져오도록 해본다!
SQL에서는 flat하게 한줄로 나오기 때문에 이에 맞춰야한다.
Copy @GetMapping("/api/v6/orders")
public List<OrderFlatDto> ordersV6(){
return orderQueryRepository.findAllByDto_flat();
}
작전 : 한번에 다 join해서 쿼리가 한번만 실행되게 한다.
=>당연히 중복 결과가 나온다!
API Specification은 이전과 동일하게 해서 중복되는 데이터들은 직접 복잡한 쿼리들을 작성해서 제거한다.
Copy @GetMapping("/api/v6/orders")
public List<OrderQueryDto> ordersV6() {
List<OrderFlatDto> flats = orderQueryRepository.findAllByDto_flat();
return flats.stream()
.collect(groupingBy(o -> new OrderQueryDto(o.getOrderId(),
o.getName(), o.getOrderDate(), o.getOrderStatus(), o.getAddress()),
mapping(o -> new OrderItemQueryDto(o.getOrderId(),
o.getItemName(), o.getOrderPrice(), o.getCount()), toList())
)).entrySet().stream()
.map(e -> new OrderQueryDto(e.getKey().getOrderId(),
e.getKey().getName(), e.getKey().getOrderDate(), e.getKey().getOrderStatus(),
e.getKey().getAddress(), e.getValue()))
.collect(toList());
}
Copy package jpabook_v2.jpashop_v2.repository.order.query;
import jpabook_v2.jpashop_v2.domain.Address;
import jpabook_v2.jpashop_v2.domain.OrderStatus;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class OrderFlatDto {
private Long orderId;
private String name;
private LocalDateTime orderDate;
private OrderStatus orderStatus;
private Address address;
private String itemName;
private int orderPrice;
private int count;
public OrderFlatDto(Long orderId, String name, LocalDateTime orderDate, OrderStatus orderStatus, Address address, String itemName, int orderPrice, int count) {
this.orderId = orderId;
this.name = name;
this.orderDate = orderDate;
this.orderStatus = orderStatus;
this.address = address;
this.itemName = itemName;
this.orderPrice = orderPrice;
this.count = count;
}
}
Copy public List<OrderFlatDto> findAllByDto_flat() {
return em.createQuery(
"select new jpabook_v2.jpashop_v2.repository.order.query.OrderFlatDto(o.id, m.name, o.orderDate, o.status, d.address, i.name, oi.orderPrice, oi.count)" +
" from Order o" +
" join o.member m" +
" join o.delivery d" +
" join o.orderItems oi" +
" join oi.item i", OrderFlatDto.class)
.getResultList();
}