본문 바로가기
Spring/JPA

[JPA] JPA(Java Persistence API)란?

by jungha_k 2022. 11. 1.

JPA란? (Java Persistence API, Jakarta Persistence)

: Java 진영에서 사용하는 ORM(객체 중심 매핑, Object-Relational Mapping) 기술의 표준 사양(명세)

 

표준 사양, 명세? - Java의 인터페이스로 사양이 정의되어 있다!

So, JPA를 구현한 구현체를 사용하고, 학습한다!

 


Hibernate ORM

: JPA 표준사양을 구현한 구현체 중 하나! (+ EclipseLink, DataNucleus...)

JPA 지원 기능 이외에 Hibernate 자체 API  또한 지원한다.

 

 

데이터 액세스 계층에서의 JPA 위치

JPA - 데이터 액세스 계층 상단

Hibernate ORM - 데이터 저장, 조회 등의 작업

JDBC API를 이용해서 데이터베이스에 접근한다.

 


JPA에서 P(Persistence)의 의미

- Persistence? 영속성, 지속성

Persistence의 목적 : 무언가를 금방 사라지지 않게하고, 오래 지속되게 한다

 

 

영속성 컨텍스트(Persistence Context)

: 테이블과 매핑되는 엔티티 객체 정보를 영속성 컨텍스트에 보관해서

애플리케이션 내에서 오래 지속되도록 함

db테이블에 데이터를 저장, 수정, 조회, 삭제하는데 사용됨!

 

 

- 1차 캐시

- 쓰기 지연 SQL 저장소

 


JPA API 동작 확인 과정

 

1. build.gradle 설정

implementation 'org.springframework.boot:spring-boot-starter-data-jpa'

 

 

 

2. application.yml 설정

  jpa:
    hibernate:
      ddl-auto: create  # (1) 스키마 자동 생성
    show-sql: true      # (2) SQL 쿼리 출력

 

 

3. Configuration 클래스 생성

 

@Configuration 을 추가하면 Spring에서 Bean 검색 대상인 Configuration 클래스로 간주한다.

@Bean 이 추가된 메서드를 검색한 후, Spring Bean으로 추가해줌

 

 

 

4. Entity 클래스 생성 (@Entity)

엔티티 클래스에 @Id, @GeneratedValue 붙이기

 

@Entity, @Id를 붙이면 JPA에서 엔티티 클래스로 인식해준다

@GeneratedValue 는 식별자를 자동으로 설정해준다 

 

 

 

5. Configuration 클래스에서

@Configuration
public class JpaBasicConfig {
    private EntityManager em;
    

    @Bean
    public CommandLineRunner testJpaBasicRunner(EntityManagerFactory emFactory) { 
        this.em = emFactory.createEntityManager();
        ...
        }
}

 

EntityManager? - JPA 영속성 클래스를 관리해준다 

EntityManagerFactory - EntityManager의 객체를 생성해준다.

 

공장(EntityManagerFactory) 에서 제품(EntityManager)을 찍어내는 개념!

 

 

https://perfectacle.github.io/2018/01/14/jpa-entity-manager-factory/


(em = EntityManager)

 

 

영속성 컨텍스트에 객체 정보를 저장할 경우

: em.persist()

 

1차 캐시에 객체가 저장되고, 이 객체는 쓰기 지연 SQL 저장소에 INSERT 쿼리 형태로 등록이 된다.

* 실제 테이블에 저장되는 것은 아니다.

 

 

 

영속성 객체가 잘 저장되었는지 확인하려면

: em.find(썸띵.클래스, 1L)로 조회한다.

=  em.find(조회할 엔티티 클래스타입, 식별자 값)

 

(1) 1차 캐시에서 해당 객체가 있는지 조회하고

(2) 없을 경우 테이블에 SELECT 쿼리를 보내 조회한다.

 

 

 

실제 테이블에 저장하고자 할 경우? 

: EntityManager 통해서 Trasaction 객체 얻음

= EntityTransaction

 

 

tx.begin() ➡ Transaction 시작

tx.commit() ➡ 영속성 컨텍스트에 저장되어있는 객체를 db 테이블에 저장

commit 을 해준 INSERT 쿼리는 실행되어 쓰기 SQL 지연소에서 사라진다

 

 

 

 

영속성 컨텍스트와 테이블에 엔티티 업데이트 할 경우

: setter 메서드 이용

 

      tx.begin();
       Member member1 = em.find(Member.class, 1L);
       member1.setEmail("hello@naver.com"); // setter 메서드로 정보 변경
       tx.commit();

 

 

 

영속성 컨텍스트와 테이블 엔티티 삭제할 경우 

: em.remove()

 

em.remove() 로 엔티티의 제거를 요청한 다음에 

tx.commit() 까지 해야 으로 제거 후, 쓰기 지연 저장소의 DELETE 쿼리가 실행이 된다.

 

 

 

em.flush()? 

: 영속성 컨텍스트의 변경 내용을 DB에 반영하는 것!

= 영속성 컨텍스트의 변경 사항과 DB 상태를 맞추고, 동기화하는 작업이다.

댓글