프로젝트 (Java)/예약마켓

[프로젝트] 47. JPQL 쿼리를 사용하여 주문 조회 로직 수정

hihyuk 2024. 2. 13. 10:19

JPQL 쿼리는 주문(Order)과 연관된 주문 항목(OrderItem) 및 상품(Item) 정보를 효율적으로 불러오는 데 도움을 줍니다. 이는 N+1 문제를 해결하고 데이터 접근 성능을 개선하는 데 유리합니다.

 

OrderRepository

public interface OrderRepository extends JpaRepository<Order, Long> {

    @Query("SELECT o FROM Order o " +
            "JOIN FETCH o.orderItems oi " +
            "JOIN FETCH oi.item i " +
            "WHERE o.user.id = :userId")
    List<Order> findByUserId(@Param("userId") Long userId);
    
    @Query("SELECT o FROM Order o " +
            "JOIN FETCH o.orderItems oi " +
            "JOIN FETCH oi.item i")
    List<Order> findAllWithItems();
}
  • findByUserId와 findAllWithItems 메소드에 @Query 어노테이션을 사용해 JPQL 쿼리를 정의합니다. 이 쿼리들은 연관된 엔티티를 JOIN FETCH를 통해 한 번의 쿼리로 가져옵니다.
  • findByUserId 메소드는 특정 사용자의 모든 주문과 그 주문에 연관된 주문 항목, 상품 정보를 가져옵니다.
  • findAllWithItems 메소드는 모든 주문과 각 주문의 주문 항목, 상품 정보를 가져옵니다.

 

OrderService

    @Transactional(readOnly = true)
    public List<OrderDto> getOrders() {
        List<Order> orders = orderRepository.findAllWithItems();
        return orders.stream().map(OrderDto::of).collect(Collectors.toList());
    }
  • getOrders 메소드에서는 OrderRepository의 findAllWithItems 메소드를 호출하여 모든 주문 정보와 연관된 주문 항목, 상품 정보를 가져옵니다.
  • 가져온 Order 엔티티 리스트를 OrderDto 객체 리스트로 변환하여 반환합니다. 이 과정에서 OrderDto::of 메소드를 사용해 Order 엔티티를 OrderDto로 변환합니다.

 

결론

이 방식으로 주문 조회 로직을 수정함으로써, 주문 정보와 그에 따른 주문 항목, 상품 정보를 효율적으로 불러올 수 있게 됩니다. 특히, JOIN FETCH를 사용함으로써 연관된 엔티티를 함께 로딩하는 방식은 성능 최적화에 큰 도움을 줍니다. 이를 통해 애플리케이션의 응답 시간을 단축하고, 사용자 경험을 향상시킬 수 있습니다.