728x90
728x90
※ 본 포스팅은 김영한 강사님의 인프런 '실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화' 강의를 들으며 작성한 수강일지 입니다.
| API 개발 고급 - 컬렉션 조회 최적화
1. 주문 조회 V1: 엔티티 직접 노출
2. 주문 조회 V2: 엔티티를 DTO로 변환
3. 주문 조회 V3: 엔티티를 DTO로 변환 - 페치 조인 최적화
4. 주문 조회 V3.1: 엔티티를 DTO로 변환 - 페이징과 한계 돌파
5. 주문 조회 V4: JPA에서 DTO 직접 조회
6. 주문 조회 V5: JPA에서 DTO 직접 조회 - 컬렉션 조회 최적화
7. 주문 조회 V6: JPA에서 DTO로 직접 조회, 플랫 데이터 최적화
8. API 개발 고급 정리
주문 조회 V5: JPA에서 DTO 직접 조회 - 컬렉션 조회 최적화
OrderApiController에 추가
// v5 - JPA에서 DTO 직접 조회
@GetMapping("/api/v5/orders")
public List<OrderQueryDto> ordersV5() {
return orderQueryRepository.findAllByDto_optimization();
}
OrderQueryRepository에 추가
public List<OrderQueryDto> findAllByDto_optimization() {
List<OrderQueryDto> result = findOrders(); // Query 1번
// // orderId의 list -> 주문번호 4, 11번이 들어있을 것
// List<Long> orderIds = toOrderIds(result);
// // 이전 v4 단점 -> loop를 돔
// Map<Long, List<OrderItemQueryDto>> orderItemMap = findOrderItemMap(orderIds);
Map<Long, List<OrderItemQueryDto>> orderItemMap = findOrderItemMap(toOrderIds(result)); // 주문 데이터 만큼 한방에 메모리에 올리고
result.forEach(o -> o.setOrderItems(orderItemMap.get(o.getOrderId()))); // loop 돌면서 모자란 부분 채워넣고
return result;
}
private Map<Long, List<OrderItemQueryDto>> findOrderItemMap(List<Long> orderIds) {
List<OrderItemQueryDto> orderItems = em.createQuery( // Query 1번 --> 총 2번 나감
"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();
// 이렇게 하면 쿼리 2번으로 최적화 가능
Map<Long, List<OrderItemQueryDto>> orderItemMap = orderItems.stream()
.collect(Collectors.groupingBy(OrderItemQueryDto::getOrderId));// orderIdf를 기준으로 Map으로 변경
return orderItemMap;
}
private static List<Long> toOrderIds(List<OrderQueryDto> result) {
List<Long> orderIds = result.stream()
.map(o -> o.getOrderId())
.collect(Collectors.toList());
return orderIds;
}
- Query: 루트 1번, 컬렉션 1번
- ToOne 관계들을 먼저 조회하고, 여기서 얻은 식별자 orderId로 ToMany 관계인 OrderItem 을 한꺼번에 조회
- MAP을 사용해서 매칭 성능 향상(O(1))
728x90
728x90
'프로그래밍 > spring boot' 카테고리의 다른 글
[스프링부트] 실전! 스프링 부트와 JPA 활용2 : 스프링 데이터 JPA, queryDSL (0) | 2023.11.26 |
---|---|
[스프링부트] 실전! 스프링 부트와 JPA 활용2 : OSIV와 성능 최적화 (0) | 2023.11.26 |
[스프링부트] 실전! 스프링 부트와 JPA 활용2 컬렉션 조회 최적화 #4 JPA에서 DTO 직접 조회 (1) | 2023.11.26 |
[스프링부트] 실전! 스프링 부트와 JPA 활용2 컬렉션 조회 최적화 #3.1 페이징과 한계 돌파 (2) | 2023.11.26 |
[스프링부트] 실전! 스프링 부트와 JPA 활용2 컬렉션 조회 최적화 #3 페치 조인 최적화 (3) | 2023.11.26 |