티스토리 뷰

주문목록 가져오기 V4

  • QueryDto를 사용해서 바로 조회하는 방법

 

쿼리용 OrderQueryDto 클래스를 선언해서 해당 타입으로 받는 api
	@GetMapping("/api/v4/orders")
	public List<OrderQueryDto> orderV4() {
		return orderQueryRepository.findOrderQueryDtos();
	}

 

OrderQueryDto
@Data
public class OrderQueryDto {

    @JsonIgnore
    private Long orderId;
    private String name;
    private LocalDateTime localDateTime;
    private OrderStatus orderStatus;
    private Address address;
    private List<OrderItemQueryDto> orderItems;

    public OrderQueryDto(Long orderId, String name, LocalDateTime localDateTime, OrderStatus orderStatus, Address address) {
        this.orderId = orderId;
        this.name = name;
        this.localDateTime = localDateTime;
        this.orderStatus = orderStatus;
        this.address = address;
    }
}

쿼리 응답을 받기위한 클래스를 선언한다. 이때 Order(1)에 포함되는 N(orderItems)를 위한 OrderItemQueryDto를 따로 선언해줘야한다.

 

OrderItemQueryDto
@Data
public class OrderItemQueryDto {
    private Long orderItemId;
    private String itemName;
    private int price;
    private int count;

    public OrderItemQueryDto(Long orderItemId, String itemName, int price, int count) {
        this.orderItemId = orderItemId;
        this.itemName = itemName;
        this.price = price;
        this.count = count;
    }
}

 

해당 쿼리 응답용 OrderQueryRepository
    public List<OrderQueryDto> findOrderQueryDtos() {
        List<OrderQueryDto> result = findOrders();

        result.forEach(o -> {
            List<OrderItemQueryDto> orderItems = findOrderItems(o.getOrderId());
            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();
    }

먼저 모든 주문을 findOrders()를 통해 찾는다. 이후 각 order에 대해서 해당 order.id와 같은 order.id를 가지는 orderitems를 찾기위해 findOrderItems()를 부른다. 반환받은 orderItems를 order의 속성값으로 넣어준다.

 

이런 구조가 되면, order목록 조회를 위해 1번의 쿼리, 각 order에서 orderItems를 조회하게 되어서 1 + N번의 쿼리가 발생한다.

 


 

반응형
Comments
반응형
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday