Java/JPA

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

Lea Hwang 2022. 5. 24. 21:33

[API 개발 고급] 시리즈 소개

현업에서 실제 발생하는 문제를 통해 어떻게 하면 API 성능최적화를 할 수 있는지 알아보는 시간입니다.

 

보통 성능문제는 등록과 수정이 아닌 "조회"에서 발생하므로 조회할 때 문제상황을 제시하고 해결해보겠습니다.

JPA N+1문제도 같이 해결해보겠습니다.

 

본격적으로 들어가기전 샘플 데이터를 입력해보겠습니다.

최종적으로 주문2건이 만들어집니다.

 

userA

  • JPA1 BOOK
  • JPA2 BOOK

userB

  • SPRING1 BOOK
  • SPRING2 BOOK

 

@Component
- 스프링 빈 등록

참고 : https://cbw1030.tistory.com/54

 

@PostConstruct
- 객체의 초기화 부분
- 객체가 생성된 후 별도의 초기화 작업을 위해 실행하는 메소드를 선언한다.
- @PostConstruct 어노테이션을 설정해놓은 init 메소드는 WAS가 띄워질 때 실행된다.

참고 : https://mangkyu.tistory.com/126

 

 

선작업

application.properties none -> create

spring.jpa.hibernate.ddl-auto=create

 

InitDb

package jpabook.jpashop;

import jpabook.jpashop.domain.*;
import jpabook.jpashop.domain.item.Book;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import javax.persistence.EntityManager;

@Component //스프링 빈 등록
@RequiredArgsConstructor
public class InitDb {

    private final InitService initService;

    @PostConstruct //초기화
    public void init() {
        initService.dbInit1();
    }

    @Component
    @Transactional
    @RequiredArgsConstructor
    static class InitService {

        private final EntityManager em;

        public void dbInit1() {
            Member member = new Member();
            member.setName("userA");
            member.setAddress(new Address("서울","888","13453"));
            em.persist(member);
            
            Book book1 = new Book();
            book1.setName("JPA1 BOOK");
            book1.setPrice(10000);
            book1.setStockQuantity(100);
            em.persist(book1);

            Book book2 = new Book();
            book2.setName("JPA2 BOOK");
            book2.setPrice(20000);
            book2.setStockQuantity(100);
            em.persist(book2);
            
            //주문 생성 메서드
            OrderItem orderItem1 = OrderItem.createOrderItem(book1, 10000, 1);
            OrderItem orderItem2 = OrderItem.createOrderItem(book2, 20000, 2);
            
            Delivery delivery = new Delivery();
            delivery.setAddress(member.getAddress());
            Order order = Order.createOrder(member, delivery, orderItem1, orderItem2);
            em.persist(order);
        }
    }


}

 

화면 랜더링

회원목록

 

상품 목록

 

주문 내역(여러건 주문해도 대표 하나만 나온다 = 회원당 주문 내역을 하나만 출력했으므로 하나만 노출된다)

 

 

DB확인

select * from member;

 

select*from orders;

 

select*from order_item;

 

userA가 JPA1 BOOK,  JPA2 BOOK을 주문한 것을 확인했습니다.

 

 

이제 userB를 같은 방식으로 코드를 작성해야하는데요, 똑같이 복붙하면 재미(?)없으니까

메서드를 뽑아내서 작성해보도록하겠습니다.

메서드 뽑아주는 단축키
Ctrl + Alt + M

 

메소드 뽑기 전

package jpabook.jpashop;

import jpabook.jpashop.domain.*;
import jpabook.jpashop.domain.item.Book;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import javax.persistence.EntityManager;

@Component //스프링 빈 등록
@RequiredArgsConstructor
public class InitDb {

    private final InitService initService;

    @PostConstruct //초기화
    public void init() {
        initService.dbInit1();
    }

    @Component
    @Transactional
    @RequiredArgsConstructor
    static class InitService {

        private final EntityManager em;

        public void dbInit1() {
            Member member = new Member();
            member.setName("userA");
            member.setAddress(new Address("서울","888","13453"));
            em.persist(member);
            
            Book book1 = new Book();
            book1.setName("JPA1 BOOK");
            book1.setPrice(10000);
            book1.setStockQuantity(100);
            em.persist(book1);

            Book book2 = new Book();
            book2.setName("JPA2 BOOK");
            book2.setPrice(20000);
            book2.setStockQuantity(100);
            em.persist(book2);
            
            //주문 생성 메서드
            OrderItem orderItem1 = OrderItem.createOrderItem(book1, 10000, 1);
            OrderItem orderItem2 = OrderItem.createOrderItem(book2, 20000, 2);
            
            Delivery delivery = new Delivery();
            delivery.setAddress(member.getAddress());
            Order order = Order.createOrder(member, delivery, orderItem1, orderItem2);
            em.persist(order);
        }

        public void dbInit2() {
            Member member = new Member();
            member.setName("userB");
            member.setAddress(new Address("제주도","10823","7950"));
            em.persist(member);

            Book book1 = new Book();
            book1.setName("SPRING1 BOOK");
            book1.setPrice(25000);
            book1.setStockQuantity(522);
            em.persist(book1);

            Book book2 = new Book();
            book2.setName("SPRING2 BOOK");
            book2.setPrice(30000);
            book2.setStockQuantity(80);
            em.persist(book2);

            //주문 생성 메서드
            OrderItem orderItem1 = OrderItem.createOrderItem(book1, 25000, 1);
            OrderItem orderItem2 = OrderItem.createOrderItem(book2, 30000, 2);

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


}

 

뽑은 후

package jpabook.jpashop;

import jpabook.jpashop.domain.*;
import jpabook.jpashop.domain.item.Book;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import javax.persistence.EntityManager;

@Component //스프링 빈 등록
@RequiredArgsConstructor
public class InitDb {

    private final InitService initService;

    @PostConstruct //초기화
    public void init() {
        initService.dbInit1();
        initService.dbInit2();
    }

    @Component
    @Transactional
    @RequiredArgsConstructor
    static class InitService {

        private final EntityManager em;

        public void dbInit1() {
            Member member = createMember("userA", "서울", "888", "13453");
            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);
        }

        public void dbInit2() {
            Member member = createMember("userB", "제주도", "10823", "7950");
            em.persist(member);

            Book book1 = createBook("SPRING1 BOOK", 25000, 522);
            em.persist(book1);

            Book book2 = createBook("SPRING2 BOOK", 30000, 80);
            em.persist(book2);

            //주문 생성 메서드
            OrderItem orderItem1 = OrderItem.createOrderItem(book1, 25000, 1);
            OrderItem orderItem2 = OrderItem.createOrderItem(book2, 30000, 2);

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

        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;
        }

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

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


}

 

DB

select * from orders;

select*from order_item;

 

 

 

 

참고 :

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-JPA-API%EA%B0%9C%EB%B0%9C-%EC%84%B1%EB%8A%A5%EC%B5%9C%EC%A0%81%ED%99%94/dashboard

 

실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화 - 인프런 | 강의

스프링 부트와 JPA를 활용해서 API를 개발합니다. 그리고 JPA 극한의 성능 최적화 방법을 학습할 수 있습니다., - 강의 소개 | 인프런...

www.inflearn.com