실전! 스프링 부트와 JPA 활용2(API 개발과 성능 최적화)

Ch02. API 개발 고급(준비) - API 개발 고급 소개, 조회용 샘플 데이터 입력

webmaster 2021. 12. 20. 10:14
728x90

API 개발 고급 - 조회용 샘플 데이터 입력

  • 등록과 수정은 성능 이슈가 거의 발생하지 않기 때문에 조회용 데이터를 입력한다.

API 개발 고급 - 지연 로딩과 조회 성능 최적화

  • N + 1 문제를 실전에서 많이 발생한다. -> 이를 해결하는 방법을 공부한다.

API 개발 고급 - 컬렉션 조회 최적화

  • 일대일, 일대다 조회를 하게 되면 데이터가 뻥튀기되는데 이때 어떻게 해결하고, 최적화하는지

API 개발 고급 - 페이징 한계 돌파

API 개발 고급 - OSIV와 성능 최적화

  • OpenSesionInView 이걸 사용하지 않는다면 Lasy로딩 Exception을 자주 만난다

샘플 데이터 입력

  • userA
    • JPA1 BOOK
    • JPA2 BOOK
  • userB
    • SPRING1 BOOK
    • SPRING2 BOOKInitDb 컴포넌트 등록
/**
 * 총 주문 2개
 * UserA
 *  JPA1 BOOK
 *  JPA2 BOOK
 * UserB
 *  SPRING1 BOOK
 *  SPRING2 BOOK
 */
@Component
@RequiredArgsConstructor
public class InitDb {

    private final InitService initService;
    
    @PostConstruct //스프링이 로딩이 되면 실행시켜준다,
    public void init(){
        initService.doInit1();
        initService.doInit2();
        //트랜잭션 떄문에 별도의 빈으로 등록해야된다.
    }
    
    
    @Component
    @Transactional
    @RequiredArgsConstructor
    static class InitService{
        private final EntityManager em;
        public void doInit1(){
            Member member = createMember("userA","서울","1","1111");
            em.persist(member);

            Book book1 = createBook("JPA1 BOOK", 10000, 100);
            em.persist(book1);

            Book book2 = createBook("JPA2 BOOK", 20000, 100);
            em.persist(book2);

            OrderItem orderItem1 = OrderItem.createOrderItem(book1,10000,1);
            OrderItem orderItem2 = OrderItem.createOrderItem(book2,20000,2);

            Delivery delivery = createDelivery(member);
            Order order = Order.createOrder(member,delivery,orderItem1,orderItem2);
            em.persist(order);
        }

        private Delivery createDelivery(Member member) {
            Delivery delivery = new Delivery();
            delivery.setAddress(member.getAddress());
            return delivery;
        }

        private Book createBook(String name, int price, int stockQuantity) {
            Book book = new Book();
            book.setName(name);
            book.setPrice(price);
            book.setStockQuantity(stockQuantity);
            return book;
        }

        private Member createMember(String name,String city,String street,String zipcode) {
            Member member = new Member();
            member.setName(name);
            member.setAddress(new Address(city,street,zipcode));
            return member;
        }

        public void doInit2(){
            Member member = createMember("userB","부산","2","2222");
            em.persist(member);

            Book book1 = createBook("SPRING1 BOOK", 20000, 200);
            em.persist(book1);

            Book book2 = createBook("SPRING2 BOOK", 40000, 300);
            em.persist(book2);

            OrderItem orderItem1 = OrderItem.createOrderItem(book1,20000,1);
            OrderItem orderItem2 = OrderItem.createOrderItem(book2,40000,2);

            Delivery delivery = createDelivery(member);
            Order order = Order.createOrder(member,delivery,orderItem1,orderItem2);
            em.persist(order);
        }
        
    }
}

 

  • 컴포넌트로 등록 후, 애플리케이션이 로딩되는 시점에 doInit1, doInit2를 호출하여 준다.
    • doInit1 = Member("userA") , Book("JPA1", "JPA2") , OrderItem((Book 1,10000,1), (Book 2,20000,2)), Delivery(), Order(member, delivery, orderItem1, orderItem2)
    • doInit2 = Member("userB") , Book("Spring1", "Spring2") , OrderItem((Book 1,20000,1), (Book 2,40000,2)), Delivery(), Order(member, delivery, orderItem1, orderItem2)

 

728x90