조회용 샘플 데이터
- userA
- userB
- SPRING1 BOOK
- SPRING2 BOOK
조회 : 지연 로딩과 조회 성능 최적화 (다대일)
엔티티를 DTO로 변환 → 페치 조인 최적화
@GetMapping("/api/v3/simple-orders")
public List<SimpleOrderDto> ordersV3() {
List<Order> orders = orderRepository.findAllWithMemberDelivery();
List<SimpleOrderDto> result = orders.stream()
.map(o -> new SimpleOrderDto(o))
.collect(toList());
return result;
}
//OrderRepository class 추가 코드
public List<Order> findAllWithMemberDelivery() {
return em.createQuery("select o from Order o" +
" join fetch o.member m" +
" join fetch o.delivery d", Order.class)
.getResultList();
}
- 엔티티를 **페치 조인(fetch join)**을 사용해서 쿼리 1번에 조회
- 페치 조인으로 order → member , order → delivery 는 이미 조회 된 상태 이므로 지연로딩X
조회 : 컬렉션 조회 최적화(일대다)
엔티티를 DTO로 변환 → 페치 조인 최적화 (distinct 사용)
@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 class 추가 코드
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();
}
- 페치 조인으로 SQL이 1번만 실행됨
- distinct를 사용한 이유는 1대다 조인이 있으므로 데이터베이스 row가 증가한다. 그 결과 같은 order 엔티티의 조회 수도 증가하게 된다. JPA의 SQL에 distinct를 추가하고, 더해서 같은 엔티티가 조회되면, 애플리케이션에서 중복을 걸러준다.
- 페이징 불가능