JPA

귀찮Lee·2022년 7월 6일
0

Spring

목록 보기
22/30

◎ JPA(Java Persistence API, Jakarta Persistence)

  • JPA

    • Java 진영에서 사용하는 ORM(Object-Relational Mapping) 기술의 표준 사양
    • Java의 인터페이스로 사양이 정의되어 있기 때문에 JPA라는 표준 사양을 구현한 구현체는 따로 있다는 것을 의미
    • JPA 에서 영속성 컨텍스트를 이용해서 DB와 데이터를 연동함
    • 구현체 : Hibernate ORM, EclipseLink, DataNucleus
      • 이 중에서 학습할 때는 Hibernate ORM 사용
      • JPA에서 지원하는 기능 이외에 Hibernate 자체적으로 사용할 수 있는 API 역시 지원함
  • 영속성 컨텍스트

    • Persistence : 무언가 금방 사라지지 않고 오래 지속되게 함
    • JPA에서 테이블과 매핑되는 객체 정보를 영속성 컨텍스트(Persistence Context)라는 곳에 보관하여, DB의 데이터를 저장, 수정, 조회, 삭제하는데 사용됨
      • 1차 캐시 : JPA에서 엔티티 정보를 저장하는 곳
      • 쓰기 지연 SQL 저장소 : 아직 DB에 보내지 않은 쿼리를 저장해놓는 곳

◎ JPA API

  • 의존 라이브러리 설정, JPA 설정

    dependencies {
        implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
        ...
    }
    # src/main/resources/application.yml
    # Shift + F6 를 통해 확장자 변경 가능
    
    spring:
      h2:
        console:
          enabled: true
          path: /h2     
      datasource:
        url: jdbc:h2:mem:test
      jpa:
        hibernate:
          ddl-auto: create  # 스키마 자동 생성
        show-sql: true      # (Run 창에) SQL 쿼리 출력
  • JPA API 메서드

    • em : EntityManager (EntityManagerFactory에서 createEntityManager 메서드를 이용해 가져옴)
    • tx : EntityTransaction (EntityManager에서 getTransaction 메서드를 통해 가져옴)
    • em.persist() : 영속성 컨텍스트에 엔티티 객체 저장
    • em.remove() : 영속성 컨텍스트에 엔티티 객체 삭제
    • em.find(Member.class, 1L) : 영속성 컨텍스트(그리고 DB)에서 데이터를 조회
    • tx.begin() : Transaction을 실행하기 위한 메서드
    • tx.commit() : 호출 시점에 영속성 컨텍스트에 저장되어 있는 객체 상황을 DB에 적용
      • em.flush() : commit 메서드 호출되면 JPA 내부적으로 flush() 메서드가 호출되어 영속성 컨텍스트의 내용을 DB에 반영
  • 샘플 코드 실행을 위한 세팅 예시

    @Configuration
    public class JpaBasicConfig {
        private EntityManager em;
        private EntityTransaction tx;
    
        @Bean // EntityManagerFactory는 DI를 통해 주입함
        public CommandLineRunner testJpaBasicRunner(EntityManagerFactory emFactory) {
            this.em = emFactory.createEntityManager();
    
            return args -> {
                Member member = new Member("example@naver.com");
    
                em.persist(member);
    
                Member resultMember = em.find(Member.class, 1L);
                System.out.println("Id: " + resultMember.getMemberId() + ", email: " + 
                        resultMember.getEmail());
            };
        }
    }

◎ JPA - 데이터 저장 과정

  • 따로 Transaction을 실행하지 않고 영속성 컨텍스트에만 저장하면,

    • 1차 캐시에 저장하고 관련 Query를 쓰기 지연 SQL 저장소에 저장함 (실제 DB에 저장되지는 않음)
  • Transaction을 실행하고 영속성 컨텍스트에 저장하고 커밋시,

    • 1차 캐시에 저장함, 커밋 전까지는 쓰기 지연 SQL 저장소 에 쿼리를 저장하기만 함
    • 커밋시에 SQL 저장소에 있는 내용을 실행함 (DB에 영속성 컨텍스트의 내용을 저장함)
    • 이후, 1차 캐시에는 객체가 있고, 쓰기 지연 SQL 저장소는 비어 있음
  • UPDATE 과정

    • em.find() 를 통해 객체를 찾음 - 처음에는 영속성 컨텍스트(1차 캐시)에서 찾고, 못찾으면 DB에 쿼리를 날려서 찾음
    • 이후 setter를 이용해 객체를 수정
    • 커밋 시점 : 데이터가 영속성 컨텍스트에 저장될 경우에는 저장되는 시점의 상태를 그대로 가지고 있는 스냅샷을 생성해 현재 시점과 비교하여 변경된 값이 있다면 쓰기 >지연 SQL 저장소에 UPDATE 쿼리를 등록하고 UPDATE 쿼리를 실행
  • DELETE 과정

    • em.find() 를 통해 객체를 찾음 - 처음에는 영속성 컨텍스트에서 찾고, 못찾으면 DB에 쿼리를 날려서 찾음
    • em.remove()를 통해 1차 캐시에 있는 엔티티 제거 요청
    • 커밋 시점 : 1차 캐시에 있는 엔티티를 제거하고, 쓰기 지연 SQL 저장소에 등록된 DELETE쿼리를 실행
profile
배운 것은 기록하자! / 오류 지적은 언제나 환영!

0개의 댓글