JPA에서 DTO로 바로 조회
controller
@GetMapping("/api/v4/simple-orders")
public List<OrderSimpleQueryDto> orderV4(){
return orderRepository.findOrderDtos();
}
repository
public List<OrderSimpleQueryDto> findOrderDtos(){
return em.createQuert(
//기존 v3 에서 엔티티로 받아올때
//"select o from Order o" , order.class //엔티티로 받아왔다.
// DTO로 받아오기1
"select new jpabook.jpashop.repository.orderSimpleQueryDto(o)" +
//DTO의 패키지 주소를 명시 , DTO의 생성자에 엔티티(o)를 넣어서생성
"from Order o" , orderSimpleQueryDto.class) //받는 타입을 엔티티에서 DTO로 변경
}
//여기서 orderSimpleQueryDto(o)로 되어있지만 orderSimpleQueryDto가 매개변수로 요구하는건 객체인데
이때 (o) 는 엔티티 상태여서 매개변수로서 적합하지 않다.
DTO로 받기 2
"select new jpabook.jpashop.repository.orderSimpleQueryDto(o.id , m.name , o.orderDate , o.status , d.address)" +
//jpa는 엔티티나 임베디드(value)만 반환할 수 있다.
위 DTO로 받아오기1에 (o) 문제를 해결
그래서 필요한 값만 뽑아 넣는 생성자를 만든다.
꼭 필요한 값만 매개변수로 넘겨주게 된다.
"from Order o" +
"join o.member m" +
"join o.addressd" , OrderSimpleQueryDto.class
DTO 로 받기 생성자
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;
}
결론적으로 위 방법으로 Repository에서 바로 DTO형식으로 데이터를 받을 수 있다.
JPA컬럼 조회시 객체 전체를 조회하는게 아니다. 원하는 컬럼만 가져와서 맵핑한 결과를 반환.
v3에 경우 패치조인을 사용해 모든 컬럼을 불러온다.
v4는 필요한 컬럼만 가져온다, 지연로딩 필드들도 다 가져와서 패치조인의 효과도 있다.
v3은 외부적 요인을 건드리지 않고 from절 내부의 요인만 건드려 가져와 재사용성이 높다.
v4는 쿼리를 외부적으로 조작해서 특정 DTO에 최적화 되었지만 그렇기에 재사용성이 낮다,.
사실 성능차이는 거의 없다.
v4가 쿼리가 더 지저분 해진다.
가급적 Repository는 엔티티와 관련된 작업만 한다.
Dto등의 작업은 Repository내에 패키지를 만들어 따로 관리한다.
가급적 V3에 패치조인으로 해결하고
불가피한 경우에만 v4를 사용한다,
'JPA' 카테고리의 다른 글
| 2월 27일 JPA 주문조회 V2 (0) | 2023.02.27 |
|---|---|
| 2월 24일 JPA API개발 고급 , 주문조회 v1 (0) | 2023.02.24 |
| 2월 23일 JPA 간단한 주문조회 V3 (0) | 2023.02.23 |
| 2월 23일 JPA 간단한 주문조회 v2 (0) | 2023.02.23 |
| 2월 22일 JPA API 개발 고급 (0) | 2023.02.22 |