JPA에서 DTO 직접 조회(collection 있을 경우)
@GetMapping("/api/v4/orders")
public List<orderQueryDTO> ordersV4(){
return orderQueryRepository.findOrderQueryDtos();
}
order와 그 Collection을 받을 DTO
//order
@Data
public class OrderQueryDTO{
private Long orderId;
private String name;
private LocalDateTime orderDate;
private OrderStatus orderStatus;
private Address address;
private List<OrderItemQueryDto> orderItems;
}
public OrderQueryDto (Long orderId , String name , LocalDateTime orderDate , OrderStatus orderStatus , Address address){
this.orderId = orderId;
this.name = name;
this.orderDate = orderDate;
this.orderStatus = orderStatus;
this.address = address;
}
//OrderItems는 바로 가져올수 없기 때문에 orderItems는 생성자에서 제외
2.Items
@Data
public class OrderItemQueryDto{
@JsonIgnore
private Long orderId;
private String itemName;
private int orderPrice;
private int count;
public OrderItemQueryDto(Long orderId , String itemName , int orderPrice , int count){
this.orderId = orderId;
this.itemName = itemName;
this.orderPrice = orderPrice;
this.count = count;
}
}
쿼리//orderItem
private List<OrderITemQueryDto> findOrderItems(Long orderId){
return em.createQuery(
"select new jpabook~orderItemQueryDto(oi.order.id , i.name , oi.orderPrice , oi.count)" +
" from OrderItem oi" +
" join oi.item i" +
" where oi.order.id = :orderId" , OrderItemQueryDto.class)
.setParameter("orderId" , orderId)
.getResultList();
}
oi.order.id 처럼 계층 탐색으로 작성가능
여기선 Item을 Join하는데 OrderItem과 item이 ManyToOne이라 row가 늘어나지 않는다. 최적화 가능
order 쿼리
public List<OrderQuertDto> findOrders(){
return em.createQuery(
"select new jpabook~OrderQueryDto(o.id , m.name , o.orderDate , o.status , d.address)" +
"from Order o" +
"join o.member m "+
"join o.delivery d" , orderQueryDto.class
).getResultList();
}
//collection값을 바로 가져올 수 없어서 따로 가져온다.
Collection 값 넣기
public List<orderQuertyDto> findOrderQueryDto(){
List<orderItemQueryDto> orderItems = findOrderItems(o.getOrderId());
//각 order의 orderId로 orderItem을 가져온다
o.setOrderItems(orderItems);
//가져온 OrderItem들을 orderDto에 넣어준다.
}
쿼리는 root는 1번 컬렉션은 N번 실행된다.
ToOne은 Join 해도 row수가 변하지 않고 ToMany는 Join시 row가 변한다
그래서 toOne은 Join해주고 toMany는 최적화가 어려우니 별도의 메서드로 값을 가져온다.
결국 위쿼리로 collection을 각각 가져오니 n+1현상이라 할 수 있다.
'JPA' 카테고리의 다른 글
| 3월 6일 JPA 주문조회 V6 (0) | 2023.03.06 |
|---|---|
| 3월 6일 JPA 주문조회 V5 (0) | 2023.03.06 |
| 2월 27일 주문조회 V3.1 (0) | 2023.02.27 |
| 2월 27일 JPA 주문조회 V3 (0) | 2023.02.27 |
| 2월 27일 JPA 주문조회 V2 (0) | 2023.02.27 |