[Spring Boot2][3] 2. API 개발 고급 - 지연 로딩과 조회 성능 최적화(2)
🏷 간단한 주문 조회 V3 : 엔티티를 DTO로 변환 - 페치 조인 최적화
✔️ OrderSimpleApiController - 추가
/**
* V3. 엔티티를 조회해서 DTO로 변환(fetch join 사용O)
* - fetch join으로 쿼리 1번 호출
* 참고: fetch join에 대한 자세한 내용은 JPA 기본편 참고(정말 중요함)
*/
@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 - 추가 코드
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
➡️ 실행하면 V2를 실행했을 때와 같은 JSON 형식이 반환됨!
그러나 쿼리 형식이 다름!!
➡️ V2는 총 5번의 쿼리가 실행됐다
➡️ 그러나 V3는 단 1번의 쿼리만 실행됐다!!
🏷 간단한 주문 조회 V4 : JPA에서 DTO로 바로 조회
✔️ OrderSimpleApiController - 추가
/**
* V4. JPA에서 DTO로 바로 조회
* - 쿼리1번 호출
* - select 절에서 원하는 데이터만 선택해서 조회
*/
@GetMapping("/api/v4/simple-orders")
public List<OrderSimpleQueryDto> ordersV4() {
return orderSimpleQueryRepository.findOrderDtos();
}
✔️ OrderSimpleQueryRepository 조회 전용 리포지토리
../repository.order.simplequery.OrderSimpleQueryRepository.java
생성
package jpabook.jpashop.repository.order.simplequery;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
import javax.persistence.EntityManager;
import java.util.List;
@Repository
@RequiredArgsConstructor
public class OrderSimpleQueryRepository {
private final EntityManager em;
public List<OrderSimpleQueryDto> findOrderDtos() {
return em.createQuery(
"select new jpabook.jpashop.repository.order.simplequery.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();
}
}
✔️ OrderSimpleQueryDto 리포지토리에서 DTO 직접 조회
../repository.order.simplequery.OrderSimpleQueryDto.java
생성
package jpabook.jpashop.repository.order.simplequery;
import jpabook.jpashop.domain.Address;
import jpabook.jpashop.domain.Order;
import jpabook.jpashop.domain.OrderStatus;
import lombok.Data;
import java.time.LocalDateTime;
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;
}
}
- 일반적인 SQL을 사용할 때 처럼 원하는 값을 선택해서 조회
new
명령어를 사용해서 JPQL의 결과를 DTO로 즉시 변환SELECT
절에서 원하는 데이터를 직접 선택하므로 DB 애플리케이션 네트워크 용량 최적화(생각보다 미비함)- 리포지토리 재사용성 떨어짐, API 스펙에 맞춘 코드가 리포지토리에 들어가는 단점이 있음
🏷 정리
쿼리 방식 선택 권장 순서
1️⃣ 우선 엔티티를 DTO로 변환하는 방법을 선택한다.
2️⃣ 필요하면 페치 조인으로 성능을 최적화 한다. 대부분의 성능 이슈가 해결된다🙂
3️⃣ 그래도 안되면 DTO로 직접 조회하는 방법을 사용한다.
4️⃣ 최후의 방법은 JPA가 제공하는 네이티브 SQL이나 스프링 JDBC Template을 사용해서 SQL을 직접 사용한다.
페치 조인의 세계란,,,,^_^
Author And Source
이 문제에 관하여([Spring Boot2][3] 2. API 개발 고급 - 지연 로딩과 조회 성능 최적화(2)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@sorzzzzy/Spring-Boot23-2.-API-개발-고급-지연-로딩과-조회-성능-최적화2저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)