JPA EntityManager詳解
EntityManager是JPA中用於增刪改查的介面,它的作用相當於一座橋樑,連線記憶體中的java物件和資料庫的資料儲存。其主要的方法定義如下:
既然EntityManager只是一個介面,那麼誰來負責實現它呢?就是實現了JPA的廠商,例如EclipseLink,Hibernate等等。那麼如何獲得EntityManager物件呢?這取決於你的EntityManger物件的託管方式,主要有以下兩種方式:
- 容器託管的EntityManager物件
- 應用託管的EntityManager物件
容器託管的EntityManager物件
容器託管的EntityManager物件最為簡單,程式設計人員不需要考慮EntityManger的連線,釋放以及複雜的事務問題等等,所有這些都交給容器來完成。
EntityManger && PersistenceContext
被EntityManager持久化到資料庫中的物件,或者從資料庫拉入記憶體中的物件,也會同時被一個持久化上下文(PersistenceContext)管理。這些被管理的物件統稱為受管物件(Managed Object),每個受管物件都有一個唯一的id。EntityManager和PersistenceContext之間的關係,一般可以是多對一的,即多個EntityManager可以同時指向一個PersistenceContext。這其實很好理解,就是EntityManager雖然有多個例項,但是它們背後的持久化上下文卻只有一個,這樣就保證了多個EntityManager所管理的受管物件擁有的ID是唯一的。
受到容器託管的EntityManager可以直接通過註解@PersistenceContext注入的方式來獲得:
@PersistenceContext
private EntityManager em;
應用託管的EntityManager物件
應用託管的EntityManager物件,程式設計師需要手動地控制它的釋放和連線、手動地控制事務等。但這種獲得應用託管的 EntityManager物件的方式,不僅可以在EJB容器中應用,也可以使 JPA脫離EJB容器,而與任何的Java環境整合,比如說Web容器、J2SE環境等。所以從某種角度上來說,這種方式是JPA能夠獨立於EJB環境運 行的基礎。
理想狀態下,最好是選用容器託管的EntityManager物件的方式,但在特殊的環境下,還是需要使用應用託管的EntityManager物件這種方式。
應用託管的EntityManger物件,通過EntityManagerFactory來獲得。
EntityManagerFactory && PersistenceUnit
EntityManagerFactory介面中使用的最為頻繁的就是第一個createEntityManager(),它能夠建立並返回得到一個EntityManager介面的實現。既然是一個用於建立EntityManager介面的工廠介面,想必就會有一個用於控制如何生產的配置場所。這個配置場所就是上圖中提到的持久化單元(Persistence Unit)。典型的比如在META-INF資料夾中建立的persistence.xml檔案,其中就可以定義一個或者多個持久化單元。
一個典型的persistence.xml檔案如下
那麼EntityManagerFactory又是通過何種方法得到的呢?這得分兩種環境來討論:
- Java EE
- Java SE
Java EE環境獲得EntityManagerFavctory
在JavaEE環境下,一般通過PersistenceUnit注入的方式引入:
@PersistenceUnit(unitName="jpa-1")
private EntityManagerFactory emf;
Java SE環境獲得EntityManagerFavctory
在JavaSE環境下,可以通過Persistence類得到具體的EntityManagerFactory實現:
EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpa-1");