< 간단한 주문조회 V2: 엔티티를 DTO로 변환 >
[ 1.구현하기 ]
{ V2용 매핑 메서드 }
// 원래는 List를 Result로 감싸는 것으로 배웠지만, 일단 학습을 위해 생략
@GetMapping("/api/v2/simple-orders")
public List<SimpleOrderDto> ordersV2() {
List<Order> orders = orderRepository.findAll();
List<SimpleOrderDto> result = orders.stream()
.map(o -> new SimpleOrderDto(o))
.collect(toList());
return result;
}
{ V2용 DTO 클래스 만들기 }
//V2용 DTO
/*
static class로 만들기
*/
static class SimpleOrderDto{
private Long orderId;
private String name;
private LocalDateTime orderDate; //주문시간
private OrderStatus orderStatus;
private Address address;
public SimpleOrderDto(Order order) {
/*
(기타) Dto가 Order엔티티를 받는 건, 괜찮다.
엔티티가 중요하다지만 엔티티 자체를 노출하는게 아니니까
*/
orderId = order.getId();
name = order.getMember().getName(); //Lazy 초기화
orderDate = order.getOrderDate();
orderStatus = order.getStatus();
address = order.getDelivery().getAddress(); //Lazy 초기화
}
}
[ 2. 한계점 ]
Lazy 조회에서 1+N 문제가 생긴다.
처음 요청에 1번의 쿼리에다가, 연결되어 조회할 엔티티에 따라 추가적인 N이 생긴다.
만약 조회결과가 N개이고, 연결되어 조회할 엔티티가 1개라면
1+N번 쿼리가 나간다.
만약 연결된 엔티티가 더 있다면 있는 만큼 +N이 늘어난다.
위의 V2에서는 member와 delivery를 2개가 있기에 N도 2번 추가된다.
즉, 조회결과가 N개라면 → 쿼리가 1+N+N번 나간다.
쿼리가 총 1 + N + N번 실행된다. (v1과 쿼리수 결과는 같다.)
order 조회 1번(order 조회 결과 수가 N이 된다.)
order -> member 지연 로딩 조회 N 번
order -> delivery 지연 로딩 조회 N 번
예) order의 결과가 4개면 최악의 경우 1 + 4 + 4번 실행된다.(최악의 경우) 지연로딩은 영속성 컨텍스트에서 조회하므로, 이미 조회된 경우 쿼리를 생략한다
생각해보자
만약 조회결과가 25개이고, 연결되어 조회할 엔티티가 4개라면???
요청 한번에 1+25+25+25 쿼리가 나간다!!! 101번 쿼리가 나가는 성능문제가 생긴다.
[ 3. 해결방법 ]
→ 페치 조인을 사용한다. → 8강
'정리 { Java 백엔드 } > (인강) JPA 프로그래밍 +스프링부트' 카테고리의 다른 글
| (JPA_활용1) _1강. 프로젝트 환경 설정 (0) | 2023.05.10 |
|---|---|
| (JPA) <6> [조회 성능 최적화] _ V1. "엔티티직접노출"의 경우 (0) | 2023.04.10 |
| (JPA) <5> API개발고급_ 조회용 샘플 데이터 입력 (0) | 2023.04.09 |
| (JPA) <3> API개발기본_회원조회API (0) | 2023.04.07 |
| <2> API개발기본_회원수정API (0) | 2023.04.06 |
댓글