728x90
@Repository
@RequiredArgsConstructor
public class OrderQueryRepository { //화면에 의존적인 쿼리는 여기서 찾는다.
private final EntityManager em;
public List<OrderQueryDto> findOrderQueryDtos() {
List<OrderQueryDto> result = findOrders(); //query 1번 -> N개
result.forEach(o ->{
List<OrderItemQueryDto> orderItems = findOrderItems(o.getOrderId()); //loof로 컬랙션을 직접채운다, query N번
o.setOrderItems(orderItems);
});
return result;
}
private List<OrderItemQueryDto> findOrderItems(Long orderId) {
return em.createQuery(
"select new jpabook.jpashop.repository.order.query.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();
}
private List<OrderQueryDto> findOrders() {
return em.createQuery(
"select new jpabook.jpashop.repository.order.query.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();
}
}


- 객체에 바로 Select 할 수 있다.
- Query: 루트 1번, 컬렉션 N 번 실행
- ToOne(N:1, 1:1) 관계들을 먼저 조회하고, ToMany(1:N) 관계는 각각 별도로 처리한다.
- 이런 방식을 선택한 이유는 다음과 같다.
- ToOne 관계는 조인해도 데이터 row 수가 증가하지 않는다.
- ToMany(1:N) 관계는 조인하면 row 수가 증가한다.
- row 수가 증가하지 않는 ToOne 관계는 조인으로 최적화하기 쉬우므로 한 번에 조회하고, ToMany 관계는 최적화하기 어려우므로 findOrderItems() 같은 별도의 메서드로 조회한다.
- OrderItemList를 Loof를 돌면서 채워줘야 된다.
728x90