JPA(Java Persistence API)

Study with cocochichi·2023년 11월 20일
post-thumbnail

JPA란?

자바 ORM 기술에 대한 API 표준이다.
즉, JAP는 인터페이스고 이를 구현한 대표적인 구현체로 Hibernate(실질적인 기능 구현), EclipseLink, DataNucleus, OpenJpa, TopLink 등이 있다.

(❔ORM : Object Relational Mapping의 약자로 객체와 관계형 데이터베이스를 매핑해주는 것)

JAP 사용 시 장점

  1. 특정 데이터베이스에 종속되지 않음
    JPA는 추상화한 데이터 접근 계층을 제공하기에 얼마든지 데이터베이스를 변경할 수 있다.

  2. 객체지향적 프로그래밍
    JPA를 사용하면 데이터베이스 설계 중심의 패러다임에서 객체지향적으로 설계가 가능해 좀 더 직관적이고 비즈니스 로직에 집중할 수 있도록 도와준다.

  3. 생산성 향상
    JPA에서는 테이블과 매핑된 클래스에 필드만 추가한다면 쉽게 관리할 수 있고, SQL문을 직접 작성하지 않고 객체를 사용하여 동작하기 때문에 유지보수 측면에서 좋고 재사용성도 증가한다.

JAP 사용 시 단점

  1. 복잡한 쿼리 처리
    통계 처리 같은 복잡한 쿼리를 사용할 경우 SQL문을 사용하는게 더 나을 수 있다. JPA에서는 Native SQL을 통해 기존의 SQL문을 사용할 수 있지만 그러면 특정 데이터베이스에 종속된다는 단점이 생긴다.

  2. 성능 저하 위험
    객체 간의 매핑 설계를 잘못했을 때 성능 저하가 발생할 수 있으며, 자동으로 생성되는 쿼리가 많기 때문에 개발자가 의도하지 않는 쿼리로 인해 성능이 저하되기도 한다.

  3. 학습 시간

JAP 동작 방식

엔티티(Entity)

  • 데이터베이스의 테이블에 대응하는 클래스
  • 데이터베이스에 item 테이블을 만들고 이에 대응되는 Item.java 클래스를 만들어서 @Entity 어노테이션을 붙이면 이 클래스가 엔티티가 되는 것

엔티티 매니저 팩토리(Entity Manager Factory)

  • 엔티티 매니저 인스턴스를 관리하는 주체
  • 애플리케이션 실행 시 한 개만 만들어지며 사용자로부터 요청이 오면 엔티티 매니저 팩토리로부터 엔티티 매니저를 생성

엔티티 매니저(Entity Manager)

  • 영속성 컨텍스트에 접근하여 엔티티에 대한 데이터베이스 작업을 제공하며 내부적으로 데이터베이스 커넥션을 사용하여 데이터베이스에 접근
  • 엔티티 매니저 메소드

    • fine() 메소드
      영속성 컨텍스트에서 엔티티를 검색하고 영속성 컨텍스트에 없을 경우 데이터베이스에서 데이터를 찾아 영속성 컨텍스트에 저장

    • persist() 메소드
      엔티티를 영속성 컨텍스트에 저장

    • remove() 메소드
      엔티티 클래스를 영속성 컨텍스트에서 삭제

    • flush() 메소드 영속성
      컨텍스트에 저장된 내용을 데이터베이스에 반영

영속성 컨텍스트

JPA를 이해하기 위해 영속성 컨텍스트를 이해하는 것이 가장 중요‼️
엔티티를 영구 저장하는 환경으로 엔티티 매니저를 통해 영속성 컨텍스트에 접근한다.

엔티티 생명주기

생명주기내용
비영속(new)new 키워드를 통해 생성된 상태로 영속성 컨텍스트와 관련이 없는 상태
영속(managed)- 엔티티가 영속성 컨텍스트에 저장된 상태로 영속성 켄텍스트에 의해 관리되는 상태
- 영속 상태에서 데이터베이스에 저장되지 않으며, 트랜잭션 및 커밋 시점에 데이터베이스에 반영
준영속 상태(detached)영속성 컨텍스트에 엔티티가 저장되었다가 분리된 상태
삭제 상태(removed)영속성 컨텍스트와 데이터베이스에서 삭제된 상태

데이터베이스 반영 코드

  1. 영속성 컨텍스트에 저장할 상품 엔티티를 하나 생성
    new 키워드를 통해 생성했으므로 영속성 컨텍스트와 관련 없는 상태
Item item = new Item();
item.setItemNm("테스트 상품");
  1. 엔티티 매니저 팩토리로부터 엔티티 매니저를 생성
EntityManager em = entityManagerFactory.createEntityManager();
  1. 엔티티 매니저는 데이터 변경 시 데이터의 무결성을 위해 반드시 트랜잭션을 시작해야함
    여기서의 트랜잭션도 데이터베이스의 트랜잭션과 같은 의미
EntityTransaction transaction = em.getTransaction();
transaction.begin();
  1. 생성한 상품 엔티티가 영속성 컨텍스트에 저장된 상태
    여기까지 데이터베이스에 INSERT SQL을 보내지 않은 단계
em.persist(item);
  1. 트랜잭션을 데이터베이스에 반영
    이때 영속성 컨텍스트에 저장된 상품 정보가 데이터베이스 INSERT 되면서 반영
transaction.commit();
  1. 엔티티 매니저와 엔티티 매니저 팩토리의 close() 메소드를 호출하여 사용한 자원 반환
em.close();
emf.close();

영속성 컨텍스트 사용 시 이점

JPA는 왜 이엃게 영속성 컨텍스트를 사용하는 것일까?
➡️ 애플리케이션과 데이터베이스 사이에 영속성 컨텍스트라는 중간 계층을 만들었기 때문

1차 캐시

  • 영속성 컨텍스트에는 1차 캐시가 존재하며 Map<KEY, VALUE>로 저장됨
  • entityManager.find() 메소드 호출 시 영속성 컨텍스트의 1차 캐시를 조회하고 엔티티가 존재할 경우 해당 엔티티를 반환하고, 없으면 데이터베이스에서 조회 후 1차 캐시에 저장 및 반환함

동일성 보장

  • 하나의 트랜잭션에서 같은 키값으로 영속성 컨텍스트에 저장된 엔티티 조회 시 같은 엔티티 조회를 보장함
    ➡️ 바로 1차 캐시에 저장된 엔티티를 조회하기 때문에 가능함

트랜잭션을 지원하는 쓰기 지연

  • 영속성 컨텍스트에는 쓰기 지연 SQL 저장소가 존재함
  • entityManager.persist()를 호출하면 1차 캐시에 저장되는 것과 동시에 쓰기 지연 SQL 저장소에서 SQL문이 저장됨
  • SQL을 쌓아두고 트랜잭션을 커밋하는 시점에 저장된 SQL문들이 flush되면서 데이터베이스에 반영됨

변경 감지

  • JPA는 1차 캐시에 데이터베이스에서 처음 불러온 엔티티의 스냅샷 값을 갖고 있음
  • 1차 캐시에 저장된 엔티티와 스냅샷을 비교 후 변경 내용이 있다면 UPDATE SQL문을 쓰기 지연 SQL저장소에 담아두고 데이터베이스에 커밋 시점에 변경 내용을 자동으로 반영함
    ➡️ 즉, 따로 update문을 호출할 필요 없음

0개의 댓글