public List<OrderQueryDto> findAllByDto_optimization(){
List<OrderQueryDto> result = findOrders();
List<Long> orderIds =result.stream()
.map(o -> o.getOrderId())
.collect(Collectors.toList());
//루트 조회(toOne 코드를 모두 한번에 조회)
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)
.setParameter("orderIds", orderIds)
.getResultList();
//orderItem 컬렉션을 MAP 한방에 조회
Map<Long, List<OrderItemQueryDto>> orderItemMap = orderItems.stream()
.collect(Collectors.groupingBy(orderItemQueryDto -> orderItemQueryDto.getOrderId()));
//루프를 돌면서 컬렉션 추가(추가 쿼리 실행X)
result.forEach(o->o.setOrderItems(orderItemMap.get(o.getOrderId())));
return result;
}
쿼리를 한 번 날린 후, 메모리에서 map하여 가져온 후 매칭
쿼리가 2번 생성이 된다
-- 루트 조회(toOne 코드를 모두 한번에 조회)
select
order0_.order_id as col_0_0_,
member1_.name as col_1_0_,
order0_.order_date as col_2_0_,
order0_.status as col_3_0_,
delivery2_.city as col_4_0_,
delivery2_.street as col_4_1_,
delivery2_.zipcode as col_4_2_
from
orders order0_
inner join
member member1_
on order0_.member_id=member1_.member_id
inner join
delivery delivery2_
on order0_.delivery_id=delivery2_.delivery_id
-- orderItem 컬렉션을 MAP 한방에 조회
select
orderitem0_.order_id as col_0_0_,
item1_.name as col_1_0_,
orderitem0_.order_price as col_2_0_,
orderitem0_.count as col_3_0_
from
order_item orderitem0_
inner join
item item1_
on orderitem0_.item_id=item1_.item_id
where
orderitem0_.order_id in (
? , ?
)