컬렉션 조회 - DTO로 변환
- 이전 V1의 엔티티 노출 문제를 해결하기 위해 DTO로 변환하여 반환해야 한다.
- 이전과 같은 방식으로 변환하되 DTO 내부에 엔티티를 두어서는 안된다.
1. 코드
@GetMapping("/api/v2/orders")
public List<OrderDto> ordersV2(){
List<Order> orders = orderRepository.findAllByString(new OrderSearch());
List<OrderDto> result = orders.stream()
.map(o -> new OrderDto(o))
.collect(toList());
return result;
}
//OrderDto
@Data
static class OrderDto {
private Long orderId;
private String name;
private LocalDateTime orderDate; //주문시간
private OrderStatus orderStatus;
private Address address;
private List<wnd> orderItems;
public OrderDto(Order order) {
this.orderId = order.getId();
this.name = order.getMember().getName();
this.orderDate = order.getOrderDate();
this.orderStatus = order.getStatus();
this.address = order.getDelivery().getAddress();
this.orderItems = order.getOrderItems().stream()
.map(o -> new OrderItemDto(o))
.collect(toList());
}
}
//OrderItemDto
@Data
static class OrderItemDto {
private String itemName;
private int orderPrice;
private int count;
public OrderItemDto(OrderItem orderItem) {
itemName = orderItem.getItem().getName();
orderPrice = orderItem.getOrderPrice();
count = orderItem.getCount();
}
}
- 이전과 같은 방식으로 DTO를 작성하였다.
- 여기서 주의 할 점은 OrderDto 내부에는 OrderItem컬렉션을 가지고 있어야 하는데, 이 컬렉션 또한 OrderItem 엔티티를 직접 노출하면 안된다는 것이다.
- 내부에 OrderItemDto을 하나 더 만들어서 OrderItem 대신 DTO를 사용하도록 설계하였다. 이때 생성자로, LAZY를 강제 초기화 해주었다.
2. 정리
LAZY방식이기 때문에 지연로딩으로 인해 너무 많은 SQL이 실행된다.
SQL 실행 수
- order 1번
- member , address N번(order 조회 수 만큼)
- orderItem N번(order 조회 수 만큼)
- item N번(orderItem 조회 수 만큼)
'JPA > API개발 및 성능 최적화' 카테고리의 다른 글
[Rest API] 14. 컬렉션 조회 - DTO조회 최적화 (0) | 2023.02.18 |
---|---|
[Rest API] 13. 컬렉션 조회 - DTO로 조회 (0) | 2023.02.17 |
[Rest API] 12. 컬렉션 조회 - 페이징 한계돌파 (0) | 2023.02.16 |
[Rest API] 11. 컬렉션 조회 - 페치조인 최적화 (0) | 2023.02.15 |
[Rest API] 9. 컬렉션 조회 - 엔티티 직접 노출 (0) | 2023.02.13 |
[Rest API] 8. 주문조회 - DTO로 바로 조회 (0) | 2023.02.12 |
[Rest API] 7. 주문조회 - 페치 조인 최적화 (0) | 2023.02.11 |
[Rest API] 6. 주문조회 - DTO로 변환 (0) | 2023.02.10 |