2월 27일 JPA 주문조회 V2
엔티티를 DTO로 반환
@GetMapping("/api/v2/orders")
public List<orderDto> ordersV2(){
List<order> orders = orderRepository.findAllByString(new orderSearch());
List<orderDTO> collect = orders.stream()
.map( o -> new OrderDTO(o))
.collect(collections.toList());
//받아온 orders값을 DTO로 변환
return collect;
}
//DTO
public class orderDTO{
private Long orderId;
private String name;
private LocalDateTime orderDate;
private OrderStatus orderStatus;
private Address address;
private List<orderItem> orderItem // 이 부분이 엔티티를 DTO로 만들때 문제
public orderDto(order order){
orderId = order.getId();
name = order.getMember.getName();
orderDate = order.getOrderDate();
orderStatus = order.getStatus();
address = order.getDelivery().getAddress();
order.getOrderItems().stream().forEach(o -> o.getItem().getName());
orderItems = order.getOrderItems();
}
}
위 방법으로는 order는 DTO로 매핑이 가능하지만
Collection필드는 엔티티 자체가 노출되버리고 만다.
해결 방법은 Collection용 DTO를 만들어 각각 매핑 해주어야 한다.
public 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();
}
}
collection 용 DTO 를 만들어주고
orderDto의 생성자에서
order.getOrderItems().stream().forEach(o -> o.getItem().getName());
orderItems = order.getOrderItems();
collection을 넣어주던 부분을
orderItem = order.getOrderItems().stream()
.map(orderItem -> new OrderItemDTO(orderItem))
.collect(collectors.toList())
위와 같이 변경해서 Collection의 요소 하나하나를 DTO로 감싸서 다시 List로 묶어준다.
위 방법으로 엔티티속 컬렉션 값타입을 각각 매핑해주어야 한다.
위 방법의 문제점은
모든 지연로딩 필드들을 각각 가져와야해서 SQL이 많이 발생한다.
패치조인을 사용하여 최적화를 더 신경써야 한다.