[3.4 간단한 주문 조회 V4] JPA에서 DTO로 바로 조회 - fetch join 비교점
JPA 에서 DTO로 조회하는 방법으로 바꿀 예정
현재 엔티티로 조회한뒤 DTO로 변환하는 상황
현재 v3 쿼리, 결과
v4 결과
쿼리가 훨씬 간단해졌다
form, join 부분은 같지만 select 부분에서 원하는것만 정확히 조회해 온다
직접 쿼리를 다 짜줘야한다는 문제점이 있다
v3, v4 의 장단점이 확실하다
v3 는 order 를 가져오는데 fetch join으로 order 내부에 원하는것을 가져오면서 최적화를 시킨것 - 외부의 모습을 건드리지 않은 상태 (order를 가져오는것은 같은상황 v2)
- [jd
- [jd
재사용성이 있다 - 엔티티 자체를 조회해 여러 DTO 로 바꿔서 받을수 있다
- [jd
재사용성이 있다 - 엔티티 자체를 조회해 여러 DTO 로 바꿔서 받을수 있다
재사용성이 있다 - 엔티티 자체를 조회해 여러 DTO 로 바꿔서 받을수 있다
- [jd
다만 성능적인 면에서 네트워크를 더 잡아먹는다 -
다만 성능적인 면에서 네트워크를 더 잡아먹는다 -
- [jd
repository 단에서 엔티티를 순수하게 조회, 단순 최적화용 페치조인을 사용하는 용도 정도는 가능하다
repository 단에서 엔티티를 순수하게 조회, 단순 최적화용 페치조인을 사용하는 용도 정도는 가능하다
v4는 sql 쿼리를 실제 짠것
- [jd
- [jd
재사용성이 아주 낮다 - 딱 맞는 DTO로 조회한것이라 바꿀수 없는 상황이다 -
- [jd
재사용성이 아주 낮다 - 딱 맞는 DTO로 조회한것이라 바꿀수 없는 상황이다 -
재사용성이 아주 낮다 - 딱 맞는 DTO로 조회한것이라 바꿀수 없는 상황이다 -
- [jd
성능적인 면에서 조금더 좋다 - 큰 차이가 나지않는다...
성능적인 면에서 조금더 좋다 - 큰 차이가 나지않는다...
- [jd
쿼리문 자체도 복잡하다
쿼리문 자체도 복잡하다
- [jd
Repository 가 엔티티의 객체 그래프를 탐색하는 용도로 조회가 되어야 하는데 API 스팩인 DTO 에 맞춰 조회한 상황 = API 스팩이 그대로 들어와 있다
Repository 가 엔티티의 객체 그래프를 탐색하는 용도로 조회가 되어야 하는데 API 스팩인 DTO 에 맞춰 조회한 상황 = API 스팩이 그대로 들어와 있다
- [jd
현재 논리적으로는 계층이 다 깨져있는 상황이다 - API(클라이언트단의 스팩) 이 달라질경우 repository를 수정해야 하는 상황이 생긴다
현재 논리적으로는 계층이 다 깨져있는 상황이다 - API(클라이언트단의 스팩) 이 달라질경우 repository를 수정해야 하는 상황이 생긴다
데이터 사이즈가 정말 많지않는한 크게 영향을 받지 않는다(컬럼 30개....데이터가 무겁다면...)
대부분 조회 성능은 조건절, join 때문에 이라서 그렇다
리포지토리는 엔티티 객체를 조회하는데 사용해야한다 -> v3 정도 까진 괜찮다
해결방법은 하위에 새로운 repository를 만들어준다
orderRepository 도 해당 페키지에 넣어준다
화면에 박힌 쿼리를 따로 뽑아낸다
OrderSimpleQueryDto.java
OrderSimpleQueryRepository.java
OrderSimpleQueryRepository.java
orderSimpleQueryRepository DI 해줘서 사용한다
일반적인 SQL을 사용할 때 처럼 원하는 값을 선택해서 조회
new 명령어를 사용해서 JPQL의 결과를 DTO로 즉시 변환
SELECT 절에서 원하는 데이터를 직접 선택하므로 DB 애플리케이션 네트웍 용량 최적화(생각보다 미비)
리포지토리 재사용성 떨어짐, API 스펙에 맞춘 코드가 리포지토리에 들어가는 단점
정리
엔티티를 DTO로 변환하거나, DTO로 바로 조회하는 두가지 방법은 각각 장단점이 있다. 둘중 상황에 따라서 더 나은 방법을 선택하면 된다. 엔티티로 조회하면 리포지토리 재사용성도 좋고, 개발도 단순해진다. - 하지만 v3 페치조인 정도는 크게 영향을 주지 않아 v3 페치조인을 잘 활용하는것이 좋다
따라서 권장하는 방법은 다음과 같다.
쿼리 방식 선택 권장 순서
1. 우선 엔티티를 DTO로 변환하는 방법을 선택한다.
2. 필요하면 페치 조인으로 성능을 최적화 한다. 대부분의 성능 이슈가 해결된다. -v3
3. 그래도 안되면 DTO로 직접 조회하는 방법을 사용한다. - v4
4. 최후의 방법은 JPA가 제공하는 네이티브 SQL이나 스프링 JDBC Template을 사용해서 SQL을 직접 사용한다.
기존 repository 에 넣었던 코드
OrderSimpleApiController.class
//dto 도 repository 쪽에 생성해준다
// - DTO의 의존관계를 controller로 보게하지 않기 위함
// 의존관계는 안으로 들어오거나, 헥사고날 아키텍처 처럼 인터페이스로 꺼내는 상황이 아니면
//의존관계는 controller -> service(repository) -> repository 로 한반향으로 흘러가는것이 좋다
OrderSimpleQueryDto.class
repository 계층에 바로 만들었다
OrderRepository.class
//엔티티나 valueObject(embeddable) 만 반환할수있다
// DTO 처럼 다른 타입을 반환하려면 new 로 생성해주고
//파라미터도 엔티티를 반환할수 없어서 식별자로 바꿔준다 (Address는 값타입이여서 가능함)
지금까지는 manyToOne 관계였다
다음은 OneToMany 관계 - 컬렉션 조회 방법을 알아본다
- [jd