public List<OrderQueryDto> findAllByDto_optimization() {
List<OrderQueryDto> result = findOrders(); //모든 order를 찾음
//모든order의 아이디를 orderIds에 저장
Map<Long, List<OrderItemQueryDto>> orderItemMap = findOrderItemMap(toOrderIds(result));
result.forEach(o -> o.setOrderItems(orderItemMap.get(o.getOrderId())));
return result;
}
private Map<Long, List<OrderItemQueryDto>> findOrderItemMap(List<Long> orderIds) {
List<OrderItemQueryDto> orderItems = em.createQuery(
"select new jpabook.jpashop.repository.order.query.OrderItemQueryDto(oi.order.id,i.name,oi.orderPrice,oi.count)" +
" from OrderItem oi" +
" join oi.item i" +
" where oi.order.id in:orderIds", OrderItemQueryDto.class)//모든 order의 아이디인 orderIds를 in으로 넣어 실행
.setParameter("orderIds", orderIds)
.getResultList();//OrderItem은 비어있음
/**
* Long에는 getOrderId, List<OrderItemQueryDto>에는 Id가 같은 OrderItemQueryDto를 List로 만들어서 넣음
*/
Map<Long, List<OrderItemQueryDto>> orderItemMap = orderItems.stream().collect(Collectors.groupingBy(orderItemQueryDto -> orderItemQueryDto.getOrderId()));
return orderItemMap;
}
private List<Long> toOrderIds(List<OrderQueryDto> result) {
return result.stream().map(o -> o.getOrderId()).collect(Collectors.toList());
}
private List<OrderQueryDto> findOrders() {
return em.createQuery(
"select new jpabook.jpashop.repository.order.query.OrderQueryDto(o.id, m.name, o.orderDate, o.status,d.address)" +
" from Order o" +
" join o.member m" +
" join o.delivery d", OrderQueryDto.class)
.getResultList();
}