본문 바로가기
JPA

자바 ORM 표준 JPA 프로그래밍 - 기본편(0)

by 임동무 2023. 1. 30.

JPA 는 어플리케이션과 JDBC 사이에서 동작하는 인터페이스의 모음이다.

JPA 를 사용하게 된다면 ORM(Object-relational mapping)

 

즉, 객체는 객체대로 설계하고 DB 는 DB 대로 설계한 후에

객체를 DB에 저장하는 과정을 ORM 프레임워크가 매핑하도록 위임할 수 있다.

 

JPA 는 객체를 분석하여 자동으로 SQL 을 생성 및 동작할 수 있으며 패러다임의 불일치 문제를 해결하여

개발자가 객체 설계와 DB 설계를 구분할 수 있도록 도와준다.

 

JPA 를 사용하게 된다면 생산성을 향상시킬 수 있고 유지보수에도 용이하다. 

가장 중요한 것은 SQL 중심 설계에서 벗어나 객체 중심적으로 설계를 할 수 있으며 

상속, 조회, 연관관계, 객체 그래프 탐색 등 패러다임의 불일치를 해결해준다.

 

JPA 에서는 JPQL 이라는 객체지향 쿼리를 사용하는데, 테이블이 아닌 객체를 대상으로 하기 때문에 DB의 SQL 에 의존하지 않는다.

 

 

JPA 에서 중요한것은 객체와 관계형 데이터베이스의 매핑 과 영속성 컨텍스트이다.

영속성 컨텍스트란 엔티티를 영구 저장하는 환경을 의미한다. 이 때, 영속성 컨텍스트는 물리적인 개념이 아닌 논리적인 개념으로

엔티티 매니저를 통해 영속성 컨텍스트에 접근할 수 있다. 

 

 

엔티티의 생명주기는

1. 영속성 컨텍스트와는 전혀 관계 없이 객체가 생성만 된 상태인 '비영속 상태'

2. 영속성 컨텍스트에 저장되어 있는 상태이며 아직 DB 에는 저장되지 않은 '영속 상태'

3. 영속성 컨텍스트에 저장되었다가 분리된 상태인 '준영속 상태'

4. 삭제된 상태인 '삭제 상태'

로 나누어진다.

 

 

Member member = new Member();

이와 같이 객체가 생성만 되어 있는 상태를 비영속 상태라고 한다. 이 때 member 객체는 영속성 컨텍스트와는 전혀 관계가 없다.

 

public class JpaMain {
    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");	// 엔티티 매니저 팩토리 생성
        EntityManager em = emf.createEntityManager();	// 엔티티 매니저 팩토리로 부터 엔티티 매니저 생성
        EntityTransaction tx = em.getTransaction();		// JPA 작업을 위해 트랜잭션 생성
        tx.begin();										// 트랜잭션 시작
        
        Member member = new Member();
        member.setName("dongmoo");
        member.setId(1L);
        em.persist(member);	// 영속화
        
        tx.commit();		// 변경사항 DB 에 반영
        em.close();			
        emf.close();
    }
}

member 객체를 영속하는 과정이다.

 

출처 : https///www.inflearn.com/course/ORM-JPA-Basic/unit/21686?category=questionDetail&q=668083

 

위 사진은 웹 어플리케이션에서 엔티티 매니저 팩토리와 엔티티 매니저의 구조를 나타낸 것이다.

먼저 모든 JPA 에서의 작업은 트랜잭션 안에서 일어난다.

위에서 처럼 요청이 들어오면, 팩토리에서 엔티티 매니저를 각 요청별로 하나씩 생성한다.

요청에 대한 작업이 이루어지는 동안 하나의 엔티티 매니저는 하나의 트랜잭션에서만 사용되며

사용 후에는 위의 코드처럼 트랜잭션을 닫아주고, 엔티티 매니저는 폐기한다.

 

 

 

영속성 컨텍스트는 1차 캐시를 사용한다.

1차 캐시를 통해 저장 및 조회를 한다. 즉, 최초 조회시에는 DB를 통해 조회하지만, 이후 동일한 엔티티를 다시 조회하는 경우 1차 캐시를 통해 조회를 하기 때문에 동일한 트랜잭션에서 조회한 동일한 엔티티는 같음을 (== 비교) 보장한다.

또한 쓰기 지연 저장소에 SQL 을 생성하여 저장하고, 커밋 시에 쿼리를 한번에 날리도록 한다.

이 때, 현재의 엔티티와 최초 조회 시점의 엔티티 스냅샷을 비교하여 변경사항이 있는 경우 변경 사항 또한 SQL 을 만들어 같이 날려주는 변경 감지 기능을 제공한다. 

 

댓글