오봉이와 함께하는 개발 블로그
JPA 2 - 간단한 주문 조회 V4 : JPA에서 DTO로 바로 조회 본문
728x90
간단한 주문 조회 V4: JPA에서 DTO로 바로 조회
OrderSimpleApiController - 추가
@GetMapping("/api/v4/simple-orders")
public List<OrderSimpleQueryDto> ordersV4() {
return orderRepository.findOrderDtos();
}
OrderSimpleQueryRepository 조회 전용 리포지토리
public List<OrderSimpleQueryDto> findOrderDtos() {
return em.createQuery("select " +
"new jpabook.jpashop.repository.OrderSimpleQueryDto(o.id, m.name, o.orderDate, o.status, d.address) " +
"from Order o " +
"join o.member m " +
"join o.delivery d", OrderSimpleQueryDto.class)
.getResultList();
}
JPA는 @Entity
나 @Embeddable
만 반환할 수 있다.(DTO를 직접 반환할 수 없다.)
그래서 꼭! new Operation
을 명시해야 한다.new Operation
을 사용할 때는 from Order o
의 o
(엔티티)를 사용하면 식별자로 넘어가기 때문에 파라미터를 직접 넣어줘야 한다.
OrderSimpleQueryDto 리포지토리에서 DTO 직접 조회
@Data
public class OrderSimpleQueryDto {
private Long orderId;
private String name;
private LocalDateTime orderDate;
private OrderStatus orderStatus;
private Address address;
public OrderSimpleQueryDto(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;
}
}
쿼리
V3
select
order0_.order_id as order_id1_6_0_,
member1_.member_id as member_i1_4_1_,
delivery2_.delivery_id as delivery1_2_2_,
order0_.delivery_id as delivery4_6_0_,
order0_.member_id as member_i5_6_0_,
order0_.order_date as order_da2_6_0_,
order0_.status as status3_6_0_,
member1_.city as city2_4_1_,
member1_.street as street3_4_1_,
member1_.zipcode as zipcode4_4_1_,
member1_.name as name5_4_1_,
delivery2_.city as city2_2_2_,
delivery2_.street as street3_2_2_,
delivery2_.zipcode as zipcode4_2_2_,
delivery2_.status as status5_2_2_
from
orders order0_
inner join
member member1_
on order0_.member_id=member1_.member_id
inner join
delivery delivery2_
on order0_.delivery_id=delivery2_.delivery_id
V4
select
order0_.order_id as col_0_0_,
member1_.name as col_1_0_,
order0_.order_date as col_2_0_,
order0_.status as col_3_0_,
delivery2_.city as col_4_0_,
delivery2_.street as col_4_1_,
delivery2_.zipcode as col_4_2_
from
orders order0_
inner join
member member1_
on order0_.member_id=member1_.member_id
inner join
delivery delivery2_
on order0_.delivery_id=delivery2_.delivery_id
from
절 아래로는 같지만 상위로는 내가 원하는 정보만 select해서 조회한다.
- 일반적인 SQL을 사용할 때 처럼 원하는 값을 선택해서 조회한다.
- new 명령어를 사용해서 JPQL의 결과를 DTO로 즉시 변환한다.
- SELECT 절에서 원하는 데이터를 직접 선택하므로 DB에서 애플리케이션으로 오는 네트워크 용량을 최적화 할 수 있다.
- row 값 몇개 더 추가하는 것 보다 join 하는 것이 더 자원을 많이 소모하기 때문에 효과는 생각보다 미비하다.
- 하지만 데이터의 사이즈가 많이 크다면 고민해보자.
- row 값 몇개 더 추가하는 것 보다 join 하는 것이 더 자원을 많이 소모하기 때문에 효과는 생각보다 미비하다.
- 리포지토리 메소드 재사용성 떨어진다.
- API 스펙에 맞춘 코드가 리포지토리에 들어가는 단점이 있다.
- 리포지토리는 엔티티를 조회하는 용도로 사용해야 하는데, DTO를 조회하는 용도가 추가되어 있기 때문에 구조가 무너진다.
- API 스펙이 변경되면 리포지토리를 다시 고쳐야 하는 단점.
API 스펙에 맞춘 코드가 리포지토리에 들어가는 단점을 해결하는 방법
// 해당 메소드를 다른 클래스에 구분지어서 만들었다.
package jpabook.jpashop.repository.order.simplequery;
@Repository
@RequiredArgsConstructor
public class OrderSimpleQueryRepository {
private EntityManager em;
public List<OrderSimpleQueryDto> findOrderDtos() {
return em.createQuery("select " +
"new jpabook.jpashop.repository.order.simplequery.OrderSimpleQueryDto(o.id, m.name, o.orderDate, o.status, d.address) " +
"from Order o " +
"join o.member m " +
"join o.delivery d", OrderSimpleQueryDto.class)
.getResultList();
}
}
화면에 종속되어 있는 코드는 따로 분리해서 작성하는 것이 유지보수에 편리함을 가져다 준다.
정리
엔티티를 DTO로 변환하거나, DTO로 바로 조회하는 두가지 방법은 각각 장단점이 있다.
둘중 상황에 따라서 더 나은 방법을 선택하면 된다.
엔티티로 조회하면 리포지토리 재사용성도 좋고, 개발도 단순해진다.
따라서 권장하는 방법은 다음과 같다.
쿼리 방식 선택 권장 순서
- 우선 엔티티를 DTO로 변환하는 방법을 선택한다.
- 필요하면 페치 조인으로 성능을 최적화 한다.
- 여기서 대부분의 성능 이슈가 해결된다.
- 그래도 안되면 DTO로 직접 조회하는 방법을 사용한다.
- 최후의 방법은 JPA가 제공하는 네이티브 SQL이나 스프링 JDBC Template을 사용해서 SQL을 직접 사용한다.
인프런 김영한 지식공유자님 강의 - 실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
728x90
'BE > JPA' 카테고리의 다른 글
JPA 2 - 주문 조회V2 : 엔티티를 DTO로 변환 (0) | 2022.09.05 |
---|---|
JPA 2 - 주문 조회 V1 : 엔티티 직접 노출 (0) | 2022.09.05 |
JPA 2 - 간단한 주문 조회 V3 : 엔티티를 DTO로 변환 (페치 조인 최적화) (0) | 2022.09.04 |
JPA 2 - 간단한 주문 조회 V2 : 엔티티를 DTO로 변환 (0) | 2022.09.04 |
JPA 2 - 간단한 주문 조회 V1 : 엔티티 직접 노출 (0) | 2022.09.04 |
Comments