분류 전체보기 1341

Ch06. SpringDataJPA,QueryDSL 맛보기 - 스프링 데이터 JPA 소개

https://spring.io/projects/spring-data Spring Data Spring Data is an umbrella project consisting of independent projects with, in principle, different release cadences. To manage the portfolio, a BOM (Bill of Materials - see this example) is published with a curated set of dependencies on the individual pr spring.io 스프링 데이터 JPA는 JPA를 사용할 때 지루하게 반복하는 코드를 자동화해준다. 이미 라이브러리는 포함되어 있다. 기존의 MemberRepos..

Ch04. API 개발 고급(컬렉션 조회 최적화) - API 개발 고급 정리

정리 엔티티 조회 엔티티를 조회해서 그대로 반환: V1 엔티티 조회 후 DTO로 변환: V2 (여러 테이블을 조인하면 성능이 안 나온다) 페치 조인으로 쿼리 수 최적화: V3 컬렉션 페이징과 한계 돌파: V3.1 (페치 조인을 하게 되면 페이징을 못하기 때문에 문제 발생) 컬렉션은 페치 조인 시 페이징이 불가능 ToOne 관계는 페치 조인으로 쿼리 수 최적화 컬렉션은 페치 조인 대신에 지연 로딩을 유지하고, hibernate.default_batch_fetch_size , @BatchSize로 최적화 DTO 직접 조회 JPA에서 DTO를 직접 조회: V4 컬렉션 조회 최적화 - 일대다 관계인 컬렉션은 IN 절을 활용해서 메모리에 미리 조회해서 최적화: V5 플랫 데이터 최적화 - JOIN 결과를 그대로 ..

Ch04. API 개발 고급(컬렉션 조회 최적화) - 주문 조회 V6(JPA에서 DTO로 직접 조회, 플랫 데이터 최적화)

통합된 DTO를 만들어서 전부 다 출력한다. @Data public class OrderFlatDto { //DB에서 한번에 다가지고온다. private Long orderId; private String name; private LocalDateTime orderDate; private OrderStatus orderStatus; private Address address; private String itemName; private int orderPrice; private int count; public OrderFlatDto(Long orderId, String name, LocalDateTime orderDate, OrderStatus orderStatus, Address address, Stri..

Ch04. API 개발 고급(컬렉션 조회 최적화) - 주문 조회 V5(JPA에서 DTO 직접 조회 (컬렉션 조회 최적화))

Controller OrderRepositoryV5 public List findAllByDtoOptimization() { List result = findOrders(); //이전꺼는 루프를 도는 단점이 있었음 Collection orderIds = toOrderIds(result); List orderItems = em.createQuery( "select new jpabook.jpashop.repository.order.query.OrderItemQueryDto(oi.order.id,i.name,oi.orderPrice,oi.count)" +" from OrderItem oi" +" join oi.item i" +" where oi.order.id in :orderIds",OrderItemQuer..

Ch04. API 개발 고급(컬렉션 조회 최적화) - 주문 조회 V4(JPA에서 DTO 직접 조회)

@Repository @RequiredArgsConstructor public class OrderQueryRepository { //화면에 의존적인 쿼리는 여기서 찾는다. private final EntityManager em; public List findOrderQueryDtos() { List result = findOrders(); //query 1번 -> N개 result.forEach(o ->{ List orderItems = findOrderItems(o.getOrderId()); //loof로 컬랙션을 직접채운다, query N번 o.setOrderItems(orderItems); }); return result; } private List findOrderItems(Long orderI..

Ch04. API 개발 고급(컬렉션 조회 최적화) - 주문 조회 V3.1(Entity를 DTO로 변환 (페이징과 한계 돌파))

컬렉션을 페치 조인하면 페이징이 불가능하다. 컬렉션을 페치 조인하면 일대다 조인이 발생하므로 데이터가 예측할 수 없이 증가한다. 일 다대에서 일(1)을 기준으로 페이징을 하는 것이 목적이다. 그런데 데이터는 다(N)를 기준으로 row 가 생성된다. Order를 기준으로 페이징 하고 싶은데, 다(N)인 OrderItem을 조인하면 OrderItem이 기준이 되어버린다. (더 자세한 내용은 자바 ORM 표준 JPA 프로그래밍 - 페치 조인 한계 참조) 이 경우 하이버네이트는 경고 로그를 남기고 모든 DB 데이터를 읽어서 메모리에서 페이징을 시도한다. 최악의 경우 장애로 이어질 수 있다. 한계 돌파 그러면 페이징 + 컬렉션 엔티티를 함께 조회하려면 어떻게 해야 할까? 지금부터 코드도 단순하고, 성능 최적화도 ..

Ch04. API 개발 고급(컬렉션 조회 최적화) - 주문 조회 V3(Entity -> DTO로 변환 ( 페치 조인 최적화))

데이터 뻥튀기 관계형 데이터 베이스는 조인을 하게 되면 주문 아이템이 2개이기 때문에 데이터가 2개가 출력이 된다. JPA 에서 일대다 조인 데이터 뻥튀기 문제 해결하기 distinct로 해결 SQL Distinct를 해준다. 단 이경우에는, 데이터가 동일해야지 중복을 제거해 주지만 join을 해서 출력되는 데이터는 다르기 때문에 dinstinct가 되지 않는다. 애플리케이션에 데이터를 가지고 와서 JPA가 알아서 중복을 제거해 준다 JPA에서 Root Entity을 중복을 제거해준다. 정리 페치 조인으로 SQL이 1번만 실행됨 distinct를 사용한 이유는 1대다 조인이 있으므로 데이터베이스 row가 증가한다. 그 결과 같은 order 엔티티의 조회 수도 증가하게 된다. JPA의 distinct는 S..

Ch04. API 개발 고급(컬렉션 조회 최적화) - 주문 조회 V2(Entity -> DTO로 변환)

앤티티를 외부로 노출하면 안 된다는 것은 DTO내부에 존재하는 모든 것들이 다 앤티티와 의존성을 끊어야 된다는 뜻이다. 내부에 만약 앤티티가 있다면 후에 앤티티가 변경되면 API스펙이 변경되므로 앤티티의 의존성을 다 제거해야 쿼리가 너무 많이 발생된다. SQL 실행 수 (최악의 경우) order 1번 member , address N번(order 조회 수 만큼) orderItem N번(order 조회 수 만큼) item N번(orderItem 조회 수 만큼 참고 : 지연 로딩은 영속성 컨텍스트에 있으면 영속성 컨텍스트에 있는 엔티티를 사용하고 없으면 SQL을 실행한다. 따라서 같은 영속성 컨텍스트에서 이미 로딩한 회원 엔티티를 추가로 조회하면 SQL을 실행하지 않는다.

Ch04. API 개발 고급(컬렉션 조회 최적화) - 주문 조회 V1(엔티티 직접 노출)

일대다 같은 경우 Collection을 조인을 하게 되는데, 데이터가 뻥튀기가 된다. 프록시 객체는 값을 채우지 않고 보내면 에러가 발생하므로 @Bean으로 하이버네이트 5 모듈을 빈으로 등록해야 된다. 양방향 연관관계면 무한 루프에 걸리지 않게 한 곳에 @JsonIgnore를 추가해야 한다. 엔티티를 직접 노출하므로 좋은 방법은 아니다.