순간을 기록으로

JPA란 무엇일까? 본문

Development/Spring

JPA란 무엇일까?

luminous13 2021. 10. 18. 15:53

JPA(Java Persistence API)란?

자바 진영에서 사용하고 있는 ORM 기술. JPA는 인터페이스이고 이를 구현한 대표적 구현체로는 Hibernate가 있다.

 

ORM(Object Relational Mapping)이란?

객체와 관계형 데이터베이스를 맵핑해주는 기술. 자바 객체와 관계형 데이터베이스 사이에서 이어준다. 이를 통해 개발자는 SQL 중심 개발에서 탈출하고 객체지향적 개발과 비즈니스 로직에 집중할 수 있다.

 

JPA 사용했을 때 장점

1. 특정 데이터베이스에 종속되지 않는다.

데이터베이스에 종속되지 않기 때문에 중간에 데이터베이스를 변경해도 문제가 없다.

 

2.객체지향적 프로그래밍을 할 수 있다.

데이터베이스 설계 중심 개발이 아닌 객체지향 중심 개발을 할 수 있다. 객체 지향적 개발을 하면 좀 더 직관적이고 비즈니스 로직에 집중할 수 있다.

 

3.생산성이 향상된다.

DB 테이블에 새로운 칼럼이 추가되면, 관련 DTO 클래스 필드를 모두 변경해야 한다. 하지만 JPA 사용자라면?! 테이블이 맵핑된 클래스에 필드만 추가하면 된다. 그리고 SQL문을 직접 작성하지 않고 객체를 사용하여 동작하기에 유지보수가 쉽다.

 

JPA 사용했을 때 단점

1.복잡한 쿼리는 다루기 어렵다.

 

2. 배우기 어렵다.

 

JPA 용어 정리

  • 엔티티(Entity)
    • 데이터베이스 테이블에 대응하는 클래스.
    • @Entity가 붙은 클래스는 JPA에서 관리하는 엔티티 클래스이다.
  • 엔티티 매니저 팩토리(Entity Manager Factory)
    • 엔티티 매니저 인스턴스를 관리한다.
    • 애플리케이션 실행 시 한 개만 만들어진다.
    • 사용자로부터 요청이 오면 엔티티 매니저를 생성한다.
  • 엔티티 매니저
    • 영속성 컨테스트(Persistent Context)에 접근하여 엔티티에 대한 데이터베이스 작업을 한다.
    • 데이터베이스 커넥션을 사용해 데이터베이스에 접근한다.
    • find()
      • 영속성 컨텍스트에서 엔티티를 검색하고 없을 영속성 컨텍스트에 없을 경우 데이터베이스에서 데이터를 찾아 영속성 컨텍스트에 저장한다.
    • persist()
      • 엔티티를 영속성 컨텍스트에 저장한다.
    • remove()
      • 엔티티 클래스를 영속성 컨텍스트에서 삭제한다.
    • flush()
      • 영속성 컨텍스트에 저장된 내용을 데이터베이스에 반영한다.
  • 영속성 컨텍스트(Persistence Context)
    • 엔티티를 영구적으로 저장하는 환경이다.
    • 엔티티 매니저를 통해 접근할 수 있다.

 

엔티티 생명주기

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

 

 

사실 위에 내용이 확 와닿지는 않는다. 코드를 통해 더 구체적으로 확인해보자.

Item item = new Item();	// 영속성 콘텍스트에 저장할 상품 엔티티를 생성합니다.
item.setItemNm("테스트 상품");

// 엔티티 매니저 팩토리부터 엔티티 매니저를 생성합니다.
EntityManager entityManager = entityManagerFactory.createEntityManager();

// 엔티티 매니저는 데이터 변경 시 데이터 무결성을 위해 반드시 트랜잭션을 해야합니다.
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();

// 생성한 상품 엔티티를 영속성 컨텍스트에 저장합니다.
// 아직 데이터베이스에 INSERT SQL을 보내지 않은 상태입니다.
entityManager.persist(item);

// 트랙잭션을 데이터베이스에 반영합니다. 
// 이때 영속성 컨텍스트에 저장된 상품 정보가 데이터베이스에 INSERT 되면서 반영됩니다
transaction.commit();

// 엔티티 매니저와 엔티티 매니저 팩토리를 close() 메소드 호출하여 사용한 자원을 반환합니다.
entityManager.close();
entityManagerFactory.close();

 

 

영속성 컨텍스트를 사용하는 이유

영속성 컨텍스트가 애플리케이션과 데이터베이스 사이에 중간계층으로 존재하기 때문이다. 이렇게 중간에 있으면 버퍼링, 캐시 등 다양한 장점이 생긴다.

 

  • 1차 캐시
    • 영속성 컨텍스트 안에 있는 캐시를 말한다.
    • 영속 상태의 엔티티를 여기에 저장한다.
    • Map<KEY, VALUE>로 저장한다.
    • entityManager.find() 메소드 호출 시 1차 캐시를 조회합니다. 엔티티가 있으면 반환하고, 없으면 데이터베이스에서 조회 후 1차 캐시에 저장 및 반환한다.
  • 동일성 보장
    • 엔티티 조회 시 같은 인스턴스를 보장한다.
  • 트랜잭션을 지원하는 쓰기 지연
    • 영속성 콘텍스트에는 SQL 저장소가 있다.
    • entityManager.persist()를 호출하면 엔티티를 1차 캐시에 저장하고 동시에 SQL 저장소에 SQL 문이 저장된다.
    • 이렇게 SQL을 쌓고 트랙잭션을 커밋하는 시점에 모든 SQL문들이 fflush되면서 데이터베이스에 반영된다. 이렇게 하면 성능에 이점이 생긴다.

 

Comments