컬렉션 조회 - 페치조인 최적화
- V2에서는 엔티티를 직접 노출하지는 않았지만 지연로딩으로 인해 SQL문이 너무 많이 나가는 문제(1 + N 쿼리)가 발생하였다.
- 이를 해결하기 위해 fetch join을 사용하여 V3를 만들어 보겠다.
1. 코드
Controller
@GetMapping("/api/v3/orders")
public List<OrderDto> ordersV3(){
List<Order> orders = orderRepository.findAllWithItem();
List<OrderDto> result = orders.stream()
.map(o -> new OrderDto(o))
.collect(toList());
return result;
}
orderRepository
public List<Order> findAllWithItem() {
return em.createQuery(
"select distinct o from Order o" +
" join fetch o.member m" +
" join fetch o.delivery d" +
" join fetch o.orderItems oi" +
" join fetch oi.item i" , Order.class)
.getResultList();
}
- Dto는 기존의 V2에서 사용된 것을 그대로 사용하였다.
정리
- 페치조인으로 인해 SQL이 1번 실행된다.
distinct
를 사용한 이유는 해당 조회를 하게되면 1대다 조인이 있으므로 데이터베이스의 row가 증가하게 된다. 따라서 같은 order 엔티티가 중복되어 나타나게 되는데 이를 방지하기 위한 distinct이다.JPA의 distinct는 SQL에 distinct기능 + 같은 엔티티가 조회되면 애플리케이션에서 중복을 걸러주는 기능을 한다.
- 하지만 페치조인이기 때문에 페이징이 불가능하다.
'JPA > API개발 및 성능 최적화' 카테고리의 다른 글
[Rest API] 15. 컬렉션 조회 - 플랫 데이터 최적화 (0) | 2023.02.19 |
---|---|
[Rest API] 14. 컬렉션 조회 - DTO조회 최적화 (0) | 2023.02.18 |
[Rest API] 13. 컬렉션 조회 - DTO로 조회 (0) | 2023.02.17 |
[Rest API] 12. 컬렉션 조회 - 페이징 한계돌파 (0) | 2023.02.16 |
[Rest API] 10. 컬렉션 조회 - DTO로 변환 (0) | 2023.02.14 |
[Rest API] 9. 컬렉션 조회 - 엔티티 직접 노출 (0) | 2023.02.13 |
[Rest API] 8. 주문조회 - DTO로 바로 조회 (0) | 2023.02.12 |
[Rest API] 7. 주문조회 - 페치 조인 최적화 (0) | 2023.02.11 |