Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- db
- Thymeleaf
- SpringBoot
- 인프런
- 스프링
- JDBC
- 백준
- Servlet
- 그리디
- spring
- 스프링 핵심 기능
- 김영한
- Android
- jpa
- 알고리즘
- AOP
- http
- Greedy
- Proxy
- JPQL
- QueryDSL
- pointcut
- kotlin
- springdatajpa
- Exception
- 자바
- java
- transaction
- 스프링 핵심 원리
- Spring Boot
Archives
- Today
- Total
개발자되기 프로젝트
컬렉션 조회 최적화 : 플랫 데이터 최적화 본문
다 조인시켜서 한방쿼리로 가져오자.
1. OrderFlatDto
- Order와 OrderItem을 join해서 DTO로 한번에 가져올 예정.
- DB에서 join하면 한줄로 쭉 join 되듯이 데이터 구조를 맞춤.
@Data
public class OrderFlatDto {
//order
private Long orderId;
private String name;
private LocalDateTime orderDate;
private OrderStatus orderStatus;
private Address address;
//orderItem
private String itemName;
private int orderPrice;
private int count;
public OrderFlatDto(Long orderId, String name, LocalDateTime orderDate, OrderStatus orderStatus, Address address, String itemName, int orderPrice, int count) {
this.orderId = orderId;
this.name = name;
this.orderDate = orderDate;
this.orderStatus = orderStatus;
this.address = address;
this.itemName = itemName;
this.orderPrice = orderPrice;
this.count = count;
}
}
2. DB에서 가져올때 OrderFlatDto로 가져오자.
public List<OrderFlatDto> findAllByDto_flat() {
return em.createQuery(
"select new " +
"springjpa2.repository.order.query.OrderFlatDto(o.id, m.name, o.orderDate, o.status, d.address, i.name, oi.orderPrice, oi.count) " +
"from Order o " +
"join o.member m " +
"join o.delivery d " +
"join o.orderItems oi " +
"join oi.item i", OrderFlatDto.class)
.getResultList();
}
3. 실행 & 결과
@GetMapping("/api/v6/orders")
public List<OrderFlatDto> ordersV6(){
return orderQueryRepository.findAllByDto_flat();
}
- order와 orderItem이 조인되어 DTO로 가져왔다.
4. 하지만 현재 반환 타입이 OrderFlatDto로
이전에 만든 v5랑 API 스펙이 다르다.
따라서 V5 API 스펙과 동일하게 맞줘야 할 필요가 있다.
어떻게? 내가 직접 중복을 거르면 된다.
그런데 o를 참조하지 못한다.. 뭐지..
- Order와 OrderItem을 하나로 합친 flasts를 루프를 돌면서
- Order와 OrderItem으로 분리하고 OrderId를 기준으로 mapping한다.
- 이후 map을 통해 OrderQueryDto로 변환한다.
@GetMapping("/api/v6/orders")
public List<OrderQueryDto> ordersV6() {
List<OrderFlatDto> flats = orderQueryRepository.findAllByDto_flat();
return flats.stream()
.collect(groupingBy(o -> new OrderQueryDto(o.getOrderId(), o.getName(), o.getOrderDate(), o.getOrderStatus(), o.getAddress()),
mapping(o -> new OrderItemQueryDto(o.getOrderId(), o.getItemName(), o.getOrderPrice(), o.getCount()), toList())
)).entrySet().stream()
.map(e -> new OrderQueryDto(e.getKey().getOrderId(), e.getKey().getName(), e.getKey().getOrderDate(), e.getKey().getOrderStatus(), e.getKey().getAddress(), e.getValue()))
.collect(toList());
}
- 위와 같이 실행하면 쿼리는 한번으로 끝이 나고
- DB에서 애플리케이션으로 보내는 중복 데이터를 직접 제거한다.
- 따라서 애플리케이션에서 추가 작업이 크고
- 페이징 불가능.(order를 기준으로 페이징 불가능)
5. GitHub : 210825 collection, flat data
'인프런 > [인프런] Springboot와 JPA활용 2' 카테고리의 다른 글
OSIV와 성능 최적화 (0) | 2021.08.26 |
---|---|
API 개발 정리 (0) | 2021.08.25 |
컬렉션 조회 : 최적화 (0) | 2021.08.25 |
컬렉션 조회: DTO 직접 조회 (0) | 2021.08.24 |
컬렉션 조회 최적화 :페이징 & batch_fetch (0) | 2021.08.24 |
Comments