Java Persistence Api(자바 영속성 api)뜻하며 ORM을 제공하는 Java의 표준 Api이다.
ORM: Java 개체를 데이터베이스 테이블에 매핑하거나 그 반대로 매핑하는 것을 ORM (Object-relational mapping)라고 한다.
JDBC를 통해서 이미 관계형 DATABASE와 JavaFrameWork끼리의 데이터 통신이 가능했다.
그럼에도 왜 JPA를 써야하는가?
그이유는 바로 객체 모델 (Java 프로그램)과 관계형 모델 (데이터베이스 프로그램) 불일치로 인해 코드가 방대해지고 복잡해지는 불편함을 줄이기 위해서다.
관계형 개체는 표 형식으로 표시되는 반면 개체 모델은 개체 형식의 상호 연결된 그래프로 표시됩니다. 관계형 데이터베이스에서 개체 모델을 저장하고 검색하는 동안 다음과 같은 이유로 일부 불일치가 발생합니다.
세분성 : 객체 모델은 관계형 모델보다 세분화됩니다. 예를들어서 객체의 경우 하나의 테이블(Class)에 관해서 복수의 Entitiy를 만들 수 있습니다.
상속 및 is,has 관계 : 하위 유형 (상속을 의미)은 모든 유형의 관계형 데이터베이스에서 지원되지 않습니다.
정체성 : 관계형 데이터베이스의 경우 기본적인 Primary Key가 항상 존재해야하고 이를 바탕으로 데이터를 비교하고 Join하게 됩니다.
연관성 : 객체 지향 언어에서 단방향 참조로 표시되는 반면 RDBMS는 외래 키 개념을 사용합니다. Java에서 양방향 관계가 필요한 경우 연관을 두 번 정의해야합니다. 마찬가지로 개체 도메인 모델을보고 관계의 다중성을 확인할 수 없습니다.
데이터 탐색 : 객체 네트워크의 객체 간 데이터 탐색은 두 모델에서 다릅니다.
package org.springframework.data.jpa.repository;
@NoRepositoryBean
public interface JpaRepository<T, ID> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> {
List<T> findAll();
List<T> findAll(Sort var1);
List<T> findAllById(Iterable<ID> var1);
<S extends T> List<S> saveAll(Iterable<S> var1);
void flush();
<S extends T> S saveAndFlush(S var1);
void deleteInBatch(Iterable<T> var1);
void deleteAllInBatch();
T getOne(ID var1);
<S extends T> List<S> findAll(Example<S> var1);
<S extends T> List<S> findAll(Example<S> var1, Sort var2);
}
다음 코드를 보면 관계형 데이터베이스를 쉽게 탐색 하고 사용할 수 있도록 메서드들이 표시되있다. 하지만 단지 인터페이스일 뿐이며 메서드에 대한 정의는 되어있지 않다. 그렇다면 JPA를 구현하고 있는곳은 어디일까?
바로 Hibernate에서 Jpa에대한 기능들에 대해 직접적으로 구현하고있다.
Hibernate는 Java 환경을위한 객체 관계형 매핑 솔루션이다. Hibernate는 애플리케이션 도메인 개체를 관계형 데이터베이스 테이블에 매핑하거나 그 반대로 매핑하기위한 프레임 워크를 제공하는 Java 기반 ORM 도구입니다. Hibernate는 느슨한 결합의 이점이있는 ORM 도구로 훌륭한 선택이되도록 Java Persistence API의 참조 구현을 제공합니다.
즉 JPA는 기술명세서이고 Hibernate는 JPA 공급자 또는 구현,설명서 입니다.
그렇다면 Hibernate는 어떻게 데이터베이스와 연결할 수 있을까?
Hibernate는 모든 데이터베이스 통신에 JDBC 를 사용한다. Hibernate는 JDBC 를 사용 하여 데이터베이스와 상호 작용한다.
그렇다면 이의 상호작용에 대해서 더 깊게 알아보자.
Hibernate Api는 어떻게 이루어져 있을까?
다음과 같이 크게 SessionFactory,EntityManager,Transaction으로 구성되어있다.
그렇다면 자세히 알아보자.
참고사항: 먼저 Session 은 hibernate내에서 제공하는 api이고 EntityManger는 JPA의 표준화된 Api이다. 그래서 세션이 EntityManger가 Session을 wrap한다고 보면된다.
Session session = entityManager.unwrap(Session.class);
Persist-context
Persist-context는 모든 Persistent entity들이 고유 한 엔티티 인스턴스가 될수 있도록 해주는 entity set이다.(주소값과 비슷함) Persist-context 내에서 엔티티는 관리 됩니다.
일반적인 EntityManager
EntityManager는 엔티티 인스턴스의 라이프 사이클을 관리하는 API이다. EntityManager 인스턴스는 Persist-context을 관리합니다. 각 EntityManager 인스턴스는 persist-context 와 연결됩니다. EntityManager는 변경 및 업데이트에 대한 persist-context 내의 모든 엔티티 객체를 추적하고 이러한 변경 사항을 데이터 베이스에 플러시합니다.
(Transaction과 유사)
Session (org.hibernate.Session)
먼저 싱글쓰레드로 구성되어져있고 단위 별 작업을 할때만 살아있다.(트랜잭션) Jpa명명법에서는 Session=EntityManager이다.
뒤에서 JDBC java.sql.Connection을 래핑하고 있고 org.hibernate.Transaction 인스턴스에 대한 팩토리 역할을 한다.
일반적으로 애플리케이션 도메인모델의 지속성 컨텍스트(첫번째 레벨 Cache)를 유지합니다.
SessionFactory (org.hibernate.SessionFactory)
이는 관계형 데이터베이스의 도메인 모델의 데이터들에 대해 thread-safe(데이터 손실없이) 하게 해준다. 위의 Session의 Instance의 Factory이다.
이때 SessionFactory=EntityManagerFactory이다.
Transaction (org.hibernate.Transaction)
개별 물리적 트랜잭션 경계를 구분하기 위해 응용 프로그램에서 사용하는 단일 스레드, 수명이 짧은 개체입니다 이때 EntityTransaction=JPA이다.
사용중인 기본 트랜잭션 시스템(JDBC)에서 Application을 분리 하는 추상화 API역할을 합니다.
1.jpa
2.jpa Architecture
3.[Hiberante]
4.hibernate and jdbc
5.EntityManager