[Spring / Java] JPA

clean·2023년 10월 15일
0

ORM

자바 객체와 관계형 데이터베이스 사이에 둘을 매핑하는 역할을 한다.
JPA는 ORM 기술의 펴준 명세로 자바에서 제공하는 API이다.

JPA

JPA는 인터페이스이고, 이를 구현한 대표적인 구현체로 Hibernate, EclipseLink, DataNucleus, OpenJpa, TopLink 등이 있다.
JPA 인터페이스를 구현한 대표적인 오픈소스가 Hibernate이다.
실질적인 기능은 Hibernate에 구현돼있다.

JPA의 동작 방식

  • Entity
    Entity는 데이터베이스의 테이블에 대응되는 클래스이다. @Entity가 붙은 클래스는 JPA에서 관리하며 엔티티라고 한다. 데이터베이스에 board라는 테이블을 만들고, Board.java라는 클래스를 만들어서 @Entity 어노테이션을 붙이면 엔티티 클래스가 되는 것이다.

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

  • Entity Manager
    엔티티 매니저는 영속성 컨택스트에 접근하여 엔티티에 대한 데이터베이스 작업을 제공한다.
    내부적으로 데이터베이스 커넥션을 사용해서 데이터베이스에 접근한다.

    • find(): 영속성 컨택스트에서 엔티티를 검색하고 영속성 컨택스트에 없을 경우 데이터베이스에서 데이터를 찾아 영속성 컨택스트에 저장한다.
    • persist(): 엔티티를 영속성 컨텍스트에 저장한다.
    • remove(): 엔티티 클래스를 영속성 컨택스트에서 삭제한다.
    • flush(): 영속성 컨텍스트에 저장된 내용을 데이터베이스에 저장한다.

영속성 컨텍스트


엔티티 생명주기

엔티티를 영구 저장하는 환경으로 엔티티 매니저를 통해 영속성 컨텍스트에 접근합니다.

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

영속성 컨텍스트를 사용하면 뭐가 좋은걸까?
바로 애플리케이션과 데이터베이스 사이에 영속성 컨텍스트라는 중간 계층을 만들고, 이 중간 계층으로 인해 버퍼링과 캐싱을 쓸 수 있다는 점이 좋은 것이다.

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

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

  • 트랜잭션을 지원하는 쓰기 지연: 영속성 컨텍스트에는 쓰기 지연 SQL 저장소가 존재한다. entityManager.persist()를 호출하면 1차 캐시에 저장되는 것과 동시에 쓰기 지연 SQL 저장소에 SQL문이 저장된다. 이렇게 SQL을 쌓아두고 트랜잭션을 커밋하는 시점에 저장된 SQL문들이 flush되며 데이터베이스에 반영된다. 이렇게 모아서 보내는 것은 성능적으로 이점을 보인다.

  • 변경 감지: JPA는 1차 캐시에 데이터베이스에서 처음 불러온 엔티티의 스냅샷을 가지고 있다. 그리고 1차 캐시에 저장된 엔티티와 스냅샷을 비교 후 변경 내용이 있다면 UPDATE SQL문을 쓰기 지연 SQL 저장소에 담아둔다. 그리고 데이터데이스 커밋 시점에 변경 내용을 자동으로 반영한다. 따로 update문을 호출할 필요가 없는 것이다.

profile
' v ' 잔디 심는 사람

0개의 댓글