OrderSimpleApiController
- V3 추가/**
* V3. 엔티티를 조회해서 DTO로 변환 (fetch join 사용 O)
* - fetch join으로 쿼리 1번 호출
*/
@GetMapping("/api/v3/simple-orders")
public List<SimpleOrderDto> orderV3() {
List<Order> orders = orderRepository.findAllWithMemberDelivery();
List<SimpleOrderDto> result = orders.stream()
.map(o -> new SimpleOrderDto(o))
.collect(toList());
return result;
}
OrderRepository
에 findAllWithMemberDelivery
추가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
는 이미 조회된 상태이므로 지연로딩 XOrderSimpleApiController
- V4 추가/**
* V4. JPA에서 DTO로 바로 조회
* - 쿼리 1번 호출
* - select 절에서 원하는 데이터만 선택해서 조회
*/
@GetMapping("/api/v4/simple-orders")
public List<OrderSimpleQueryDto> orderV4() {
return orderSimpleQueryRepository.findOrderDtos();
}
OrderSimpleQueryRepository
생성@Repository
@RequiredArgsConstructor
public class OrderSimpleQueryRepository {
private final EntityManager em;
public List<OrderSimpleQueryDto> findOrderDtos() {
return em.createQuery(
"select new jpabook.jpashop.repository.order.OrderSimpleQueryDto(o.id, m.name, o.orderDate, o.status, d.address)" +
" from Order o" +
" join o.member m" +
" join o.delivery d", OrderSimpleQueryDto.class)
.getResultList();
}
}
new
를 이용해서 객체를 생성할 때 full package path
를 입력해야 한다.OrderSimpleQueryDto
생성@Data
public class OrderSimpleQueryDto {
private Long orderId;
private String name;
private LocalDateTime orderDate; //주문 시간
private OrderStatus orderStatus;
private Address address;
public OrderSimpleQueryDto(Long orderId, String name, LocalDateTime orderDate, OrderStatus orderStatus, Address address) {
this.orderId = orderId;
this.name = name;
this.orderDate = orderDate;
this.orderStatus = orderStatus;
this.address = address;
}
}
new
명령어를 사용해서 JPQL의 결과를 DTO로 즉시 변환한다.📌 정리
엔티티를 DTO로 변환하거나(V3), DTO로 바로 조회하는 방법(V4)은 각각 장단점이 있다. 그래서 사실 우열을 가리기는 힘들다!
V3보다 V4가 성능 최적화는 되었지만, 재사용성이 좋지 않다.
💡 쿼리 방식 선택 권장 순서
- 우선 엔티티를 DTO로 변환하는 방법을 선택한다.
- 필요하면 페치 조인으로 성능을 최적화한다. → 대부분의 성능 이슈가 해결된다.
- 그래도 안되면 DTO로 직접 조회하는 방법을 사용한다.
- 최후의 방법은 JPA가 제공하는 네이티브 SQL이나 스프링 JDBC Template을 사용해서 SQL을 직접 사용한다.