API

1. OSIV JPA에서 EntityManager가 하이버네이트 에서는 Session이라고 한다. 여기서 말하는 Session이란 사용자의 데이터를 저장해주는 곳이 아니다. 따라서 OSIV(Open Session In View) 는 하이버네이트, OEIV(Open EntityManager In View) 는 JPA에서 사용된다. OSIV는 말 그대로 영속성 컨텍스트를 뷰 까지 열어두는 기능이다. Spring.jpa.open-in.view는 기본값이 True이다. 1)True 해당 값을 True로 하게 되면 트랜젝션 시작 시점에 DB와 커넥션을 맺는 영속성 컨텍스트가 생성되고 API응답이 끝날 때까지 영속성 컨텍스트와 DB커넥션을 유지한다. 따라서 지금까지 View Template이나 API Control..
V1. 엔티티 직접 노출 엔티티가 변하면 API 스펙이 변한다. 트랜잭션 안에서 지연 로딩 필요(1 + N Query) 양방향 연관관계 문제 V2. 엔티티를 조회해서 DTO로 변환(fetch join 사용X) 트랜잭션 안에서 지연 로딩 필요(1 + N Query) V3. 엔티티를 조회해서 DTO로 변환(fetch join 사용O) 페이징 시에는 N 부분을 포기해야함(대신에 batch fetch size? 옵션 주면 N -> 1 쿼리로 변경 가능) V4. JPA에서 DTO로 바로 조회, 컬렉션 N 조회 (1 + N Query) 페이징 가능 V5. JPA에서 DTO로 바로 조회, 컬렉션 1 조회 최적화 버전 (1 + 1 Query) 페이징 가능 V6. JPA에서 DTO로 바로 조회, 플랫 데이터 (1 Que..
1. 컬렉션 조회 - 플랫 데이터 최적화 V5는 괜찮게 최적화 되었지만 여전히 쿼리가 2번 나간다. 이를 1번만 나가게 하는 방법을 알아보겠다. 방법은 간단하다. 필요한 모든 데이터를 담은 DTO를 새로 만들고, 해당 데이터를 모두 가져와서 우리가 원래 반환 하려는 DTO로 변환해주면 된다. 1. DTO 생성 컬렉션 필드의 값을 채워 넣는 과정을 없애기 위해서 새로운 DTO가 필요하다. @Data public class OrderFlatDto { private Long orderId; private String name; private LocalDateTime orderDate; private OrderStatus orderStatus; private Address address; // 컬렉션 필드 대신..
컬렉션 조회 - DTO 조회 최적화 기존 V4방식에서 1 + N번 쿼리가 나가는 것을 1 + 1번 쿼리가 나가도록 하는 것이다. In절을 이용한다. public List findAllByDto() { List result = findOrders(); List orderIds = result.stream().map(o -> o.getOrderId()).collect(Collectors.toList()); List orderItems = em.createQuery( "select new jpabook.jpabook.dto.OrderItemQueryDto(oi.order.id, i.name, oi.orderPrice, oi.count) " + "from OrderItem oi " + "join oi.item ..
컬렉션 조회 - DTO로 직접 조회 1. 코드 DTO 변환 조회 메서드의 코드는 다음과 같다. @GetMapping("/api/v3/orders") public List ordersV3() { List orders = orderRepository.findAllWithItem(); List result = orders.stream() .map(o -> new OrderDto(o)).collect(Collectors.toList()); return result; } 1. DTO 생성 @Data public class OrderQueryDto { private Long orderId; private String name; private LocalDateTime orderDate; private OrderSta..
컬렉션 조회 - 페이징 V3버전은 페치 조인으로 1 + N 문제를 해결하였지만 페이징이 불가능 하다는 단점이 있었다. 페이징이 가능한 V3.1 버전을 만들어 보도록 하겠다. 1. 코드 Controller @GetMapping("/api/v3.1/orders") public List ordersV3_page( @RequestParam(value = "offset", defaultValue = "0") int offset, @RequestParam(value = "limit", defaultValue = "100") int limit) { List orders = orderRepository.findAllWithMemberDelivery(offset, limit); List result = orders.st..
컬렉션 조회 - 페치조인 최적화 V2에서는 엔티티를 직접 노출하지는 않았지만 지연로딩으로 인해 SQL문이 너무 많이 나가는 문제(1 + N 쿼리)가 발생하였다. 이를 해결하기 위해 fetch join을 사용하여 V3를 만들어 보겠다. 1. 코드 Controller @GetMapping("/api/v3/orders") public List ordersV3(){ List orders = orderRepository.findAllWithItem(); List result = orders.stream() .map(o -> new OrderDto(o)) .collect(toList()); return result; } orderRepository public List findAllWithItem() { retur..
컬렉션 조회 - DTO로 변환 이전 V1의 엔티티 노출 문제를 해결하기 위해 DTO로 변환하여 반환해야 한다. 이전과 같은 방식으로 변환하되 DTO 내부에 엔티티를 두어서는 안된다. 1. 코드 @GetMapping("/api/v2/orders") public List ordersV2(){ List orders = orderRepository.findAllByString(new OrderSearch()); List result = orders.stream() .map(o -> new OrderDto(o)) .collect(toList()); return result; } //OrderDto @Data static class OrderDto { private Long orderId; private Strin..
컬렉션 조회 - 엔티티 직접 노출 지금까지 OrderSimpleApiController를 작성하면서 간단한 OrderApiController를 만들어 보았다. Order에는 List 필드가 있는데 해당 컬렉션 필드는 ToOne관계가 아니라 ToMany 관계이기 때문에 다루지 않았었다. 지금부터는 Order에 컬렉션 필드를 추가하여 조회하는 방법을 알아보고자 한다. 1. 코드 @GetMapping("/api/v1/orders") public List ordersv1() { List all = orderRepository.findAllByString(new OrderSearch()); for (Order order : all) { order.getMember().getName(); order.getDeliv..
주문조회 V4 - JPA에서 DTO로 바로 조회 V4: JPA에서 DTO로 바로 조회하여 Select절에서 원하는 데이터만 선택하여 조회하는 방법을 알아보겠다. @GetMapping("/api/v4/simple-orders") public List ordersV4() { return orderSimpleQueryRepository.findOrderDtos(); } Controller에 다음 코드를 추가한다. 이전 V3와 다른점이 보일 것이다. 바로 기존 DTO가 아니라 새로운 DTO로 반환한다. 또한, 참조하는 레포지토리도 변경되었다. 또, 엔티티를 DTO로 변환하는 작업도 없어진 것을 볼 수 있다. 지금부터 하나하나 설명 하겠다. 우선 새로 만든 레포지토리 이다. @Repository @Required..
코드 미식가
'API' 태그의 글 목록