오봉이와 함께하는 개발 블로그
JPA 2 - 주문 조회V5 : JPA에서 DTO 직접 조회(컬렉션 조회 최적화) 본문
728x90
주문 조회 V5: JPA에서 DTO 직접 조회 - 컬렉션 조회 최적화
OrderApiController에 추가
@GetMapping("/api/v5/orders")
public List<OrderQueryDto> ordersV5() {
return orderQueryRepository.findAllByDto_optimization();
}
OrderQueryRepository에 추가
/**
* 최적화
* Query: 루트 1번, 컬렉션 1번
* 데이터를 한꺼번에 처리할 때 많이 사용하는 방식
*/
public List<OrderQueryDto> findAllByDto_optimization() {
//루트 조회(toOne 코드를 모두 한번에 조회)
List<OrderQueryDto> result = findOrders();
//orderItem 컬렉션을 MAP을 통해 한번에 조회(루프를 돌지 않고 in 쿼리 사용)
List<Long> orderIds = toOrderIds(result);
Map<Long, List<OrderItemQueryDto>> orderItemMap = findOrderItemMap(orderIds);
//루프를 돌면서 컬렉션 추가(추가 쿼리 실행X)
result.forEach(o -> o.setOrderItems(orderItemMap.get(o.getOrderId())));
return result;
}
private List<Long> toOrderIds(List<OrderQueryDto> result) {
return result.stream()
.map(o -> o.getOrderId())
.collect(Collectors.toList());
}
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)
.setParameter("orderIds", orderIds)
.getResultList();
Map<Long, List<OrderItemQueryDto>> orderItemMap = orderItems.stream()
.collect(Collectors.groupingBy(orderItemQueryDto -> orderItemQueryDto.getOrderId()));
// orderItemQueryDto의 orderId를 기준으로 해서 List를 Map으로 바꿔줌.
// key = orderItemQueryDto.getOrderId(), value = List<OrderItemQueryDto>
return orderItemMap;
}
}
정리
V4
는 루프를 돌릴 때 마다 쿼리를 날렸는데 V5
는 쿼리를 1번 날리고 메모리에 맵으로 가져온 후 메모리에서 매칭을 통해 값을 세팅해준다.
쿼리가 총 2번 나간다.
XToOne
관계들을 먼저 조회하고, 여기서 얻은 식별자 orderId
로 XToMany
관계인 OrderItem
을 IN
쿼리를 통해 한꺼번에 조회한다.
- Query
- 루트 1번
- 컬렉션 1번
- MAP을 사용해서 매칭 성능 향상(O(1))
인프런 김영한 지식공유자님 강의 - 실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
728x90
'BE > JPA' 카테고리의 다른 글
JPA 2 - API 개발 고급 정리 (0) | 2022.09.07 |
---|---|
JPA 2 - 주문 조회 V6 : JPA에서 DTO로 직접 조회(플랫 데이터 최적화) (0) | 2022.09.06 |
JPA 2 - 주문 조회V4 : JPA에서 DTO 직접 조회 (0) | 2022.09.06 |
JPA 2 - 주문 조회V3.1 : 엔티티를 DTO로 변환(페이징과 한계 돌파) (0) | 2022.09.06 |
JPA 2 - 주문 조회V3 : 엔티티를 DTO로 변환(페치 조인 최적화) (0) | 2022.09.05 |
Comments