JPA

2월 27일 JPA 주문조회 V2

Chaerin Yoo 2023. 2. 27. 16:10

엔티티를 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이 많이 발생한다.

패치조인을 사용하여 최적화를 더 신경써야 한다.