728x90
728x90
※ 본 포스팅은 김영한 강사님의 인프런 '실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화' 강의를 들으며 작성한 수강일지 입니다.
| API 개발 고급 - 지연 로딩과 조회 성능 최적화
1. 간단한 주문 조회 V1: 엔티티를 직접 노출
2. 간단한 주문 조회 V2: 엔티티를 DTO로 변환
3. 간단한 주문 조회 V3: 엔티티를 DTO로 변환 - 페치 조인 최적화
4. 간단한 주문 조회 V4: JPA에서 DTO로 바로 조회
4. 간단한 주문 조회 V4: JPA에서 DTO로 바로 조회
OrderSimpleApiController - 추가
// v3와 join은 같지만 select절에서 내가 원하는 것만 조회
@GetMapping("/api/v4/simple-orders")
public List<OrderSimpleQueryDto> ordersV4() {
return orderRepository.findOrdersDtos();
}
@Data
static class SimpleOrderDto {
private Long orderId;
private String name;
private LocalDateTime orderDate;
private OrderStatus orderStatus;
private Address address;
public SimpleOrderDto(Order order) { // 생성자
orderId = order.getId();
name = order.getMember().getName(); //LAZY 초기화
orderDate = order.getOrderDate();
orderStatus = order.getStatus();
address = order.getDelivery().getAddress(); //LAZY 초기화
}
}
OrderRepository
public List<OrderSimpleQueryDto> findOrdersDtos() {
return em.createQuery("select new jpabook.jpashop.repository.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
package jpabook.jpashop.repository;
import jpabook.jpashop.domain.Address;
import jpabook.jpashop.domain.Order;
import jpabook.jpashop.domain.OrderStatus;
import lombok.Data;
import java.time.LocalDateTime;
@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; //LAZY 초기화
this.orderDate = orderDate;
this.orderStatus = orderStatus;
this.address = address; //LAZY 초기화
}
}
- 일반적인 SQL을 사용할 때 처럼 원하는 값을 선택해서 조회
- new 명령어를 사용해서 JPQL의 결과를 DTO로 즉시 변환
- SELECT 절에서 원하는 데이터를 직접 선택하므로 DB -> 애플리케이션 네트웍 용량 최적화(생각보다 미비)
- 리포지토리 재사용성 떨어짐, API 스펙에 맞춘 코드가 리포지토리에 들어가는 단점
정리
엔티티를 DTO로 변환하거나, DTO로 바로 조회하는 두가지 방법은 각각 장단점이 있다. 둘중 상황에 따라서 더 나은 방법을 선택하면 된다. 엔티티로 조회하면 리포지토리 재사용성도 좋고, 개발도 단순해진다. 따라 서 권장하는 방법은 다음과 같다.
쿼리 방식 선택 권장 순서
- 우선 엔티티를 DTO로 변환하는 방법을 선택한다. (코드 유지보수성에서 나음)
- 필요하면 페치 조인으로 성능을 최적화 한다 -> 대부분의 성능 이슈가 해결된다. <- 여기까지가 ~v3
- 그래도 안되면 DTO로 직접 조회하는 방법을 사용한다. (v4 처럼)
- 최후의 방법은 JPA가 제공하는 네이티브 SQL이나 스프링 JDBC Template을 사용해서 SQL을 직접 사용한다.
repository : 가급적이면 순수한 entity를 조회하는데 사용해야 하고, 필요하면 성능 최적화를 위해 fetch join 하는 정도
v4는 화면에 박인 것, 복잡한 query로 dto를 뽑아내야 할 때. 용도가 애매해지고 유지보수하기 힘듦. 화면용으로 조회하는 용도로 쓴다고 알 수 있도록 따로 뺌
728x90
728x90
'프로그래밍 > spring boot' 카테고리의 다른 글
[스프링부트] 실전! 스프링 부트와 JPA 활용2 컬렉션 조회 최적화 #2 엔티티를 DTO로 변환 (0) | 2023.11.26 |
---|---|
[스프링부트] 실전! 스프링 부트와 JPA 활용2 컬렉션 조회 최적화 #1 엔티티 직접 노출 (2) | 2023.11.26 |
[스프링부트] 실전! 스프링 부트와 JPA 활용2 지연 로딩과 조회 성능 최적화 #1 간단한 주문 조회 V3: 엔티티를 DTO로 변환 - 페치 조인 최적화 (0) | 2023.11.25 |
[스프링 입문] 스프링을 공부해야 하는 이유? (2) | 2023.11.25 |
[Annotations] Spring Boot Annotation 정리 (1) | 2023.11.23 |