이전 코드에서 더 최적화를 해서 쿼리 한방으로 해결되는 방법을 알아보겠습니다.
@GetMapping("/api/v6/orders")
public List<OrderFlatDto> ordersV6() {
return orderQueryRepository.findAllByDto_flat();
}
@Data
public class OrderFlatDto { //...1
private Long orderId;
private String name;
private LocalDateTime orderDate;
private OrderStatus orderStatus;
private Address address;
private String itemName;
private int orderPrice;
private int count;
public OrderFlatDto(Long orderId, String name, LocalDateTime orderDate, OrderStatus orderStatus, Address address, String itemName, int orderPrice, int count) {
this.orderId = orderId;
this.name = name;
this.orderDate = orderDate;
this.orderStatus = orderStatus;
this.address = address;
this.itemName = itemName;
this.orderPrice = orderPrice;
this.count = count;
}
}
Order 와 OrderItem 을 조인하고 OrderItem 와 Item 을 조인해서 모든 데이터를 한 번에 다 가져오기 위한 DTO 입니다.
DB 에서 데이터를 한 줄로 플랫하게 가져올 수 있도록 데이터 구조를 맞춰야 합니다.
public List<OrderFlatDto> findAllByDto_flat() {
return em.createQuery(
"select new jpabook.jpashop.repository.order.query.OrderFlatDto(o.id, m.name, o.orderDate, o.status, d.address, i.name, oi.orderPrice, oi.count)" +
" from Order o" +
" join o.member m" +
" join o.delivery d" +
" join o.orderItems oi" +
" join oi.item i", OrderFlatDto.class)
.getResultList();
}
실행을 해봅시다.
[
{
"orderId": 4,
"name": "userA",
"orderDate": "2024-04-22T10:36:12.922416",
"orderStatus": "ORDER",
"address": {
"city": "서울",
"street": "1",
"zipcode": "1111"
},
"itemName": "JPA1 BOOK",
"orderPrice": 10000,
"count": 1
},
{
"orderId": 4,
"name": "userA",
"orderDate": "2024-04-22T10:36:12.922416",
"orderStatus": "ORDER",
"address": {
"city": "서울",
"street": "1",
"zipcode": "1111"
},
"itemName": "JPA2 BOOK",
"orderPrice": 20000,
"count": 2
},
{
"orderId": 11,
"name": "userB",
"orderDate": "2024-04-22T10:36:13.043211",
"orderStatus": "ORDER",
"address": {
"city": "진주",
"street": "2",
"zipcode": "2222"
},
"itemName": "SPRING1 BOOK",
"orderPrice": 20000,
"count": 3
},
{
"orderId": 11,
"name": "userB",
"orderDate": "2024-04-22T10:36:13.043211",
"orderStatus": "ORDER",
"address": {
"city": "진주",
"street": "2",
"zipcode": "2222"
},
"itemName": "SPRING2 BOOK",
"orderPrice": 40000,
"count": 4
}
]
데이터가 중복이 돼서 응답하고 있습니다.
실제 JPA 가 만들어주는 쿼리를 봅시다.
쿼리를 직접 실행하면 총 로우가 4개 나옵니다.