JPA中要對資料庫進行操作前,必須先取得EntityManager實例,這有點類似JDBC在對資料庫操作之前,必須先取得Connection實例,EntityManager是JPA操作的基礎,它不是設計為執行緒安全(Thread-safe)。
EntityManager實例基本上是從EntityManagerFactory上呼叫createEntityManager()方法來取得,在 第一個 JPA(單機客戶端) 中有看到實際的例子,若您使用容器管理,則可以使用@PersistenceContext注入EntityManger,像是 第一個 JPA(容器管理) 所示範的,或者您可以使用@PersistenceUnit注入EntityManagerFactory,再用它來建立EntityManager,如 在 Servlet 中直接使用 JPA 所示範的。
EntityManager主要在管理Entity實例生命週期,透過EntityManager,您對Entity實例的操作,可以對應至資料庫進行新增、查找、修改、刪除、重清等動作,以下先簡介API的使用,以Application-Managed EntityManager爲例作說明,您必須搭配 Entity 生命週期 以對Entity在EntityManager中的Managed、Detached、Removed狀態獲得更進一步的了解。
要新增資料,可以使用EntityManager的persist()方法,這也會讓Entity實例處於Managed狀態,例如:
User user = new User();
// 設定 user 相關屬性
entityManager.persist(user);
// 設定 user 相關屬性
entityManager.persist(user);
若要取得資料表中的資料,使用EntityManager的find()方法,指定主鍵物件與Class實例來取得對應的資料並封裝為物件,查找回的物件會處於Managed的狀態:
User user = entityManager.find(User.class, id);
若資料庫中已有對應資料,則要修改資料有幾種方式:
- 若物件是在Managed狀態,例如查找物件之後,直接更新物件,在交易確認之後,物件的更新就會反應至資料表之中:
User user = entityManager.find(User.class, id);
user.setName("Justin Lin");
user.setName("Justin Lin");
- 若物件屬於生命週期的Detached狀態,您可以使用EntityManager的merge()方法將物件轉至生命周期的Managed狀態,合併物件上之變更:
// 若 user 狀態有所變動
entityManager.merge(user);
entityManager.merge(user);
- 也可以先使用merge()方法將Detached狀態的Entity實例轉至Managed的狀態,再更新物件,在交易確認之後,物件的更新就會反應至資料表之中:
User user1 = entityManager.merge(user);
user1.setName("Justin Lin");
user1.setName("Justin Lin");
若要刪除資料表中的資料,則物件必須是在Managed的狀態,例如用EntityManager的find()方法查找物件,以查找到的物件配合remove()方法來移除,或是使用merge(()方法將Entity處於Managed狀態再用remove()移除,移除之後,物件對應不到資料表格中實際的資料,處於Removed狀態:
User user = entityManager.find(User.class, id);
entityManager.remove(user);
entityManager.remove(user);
若在載入某個Entity實例之後,而資料表格因另一個操作而發生變動,您可以使用EntityManager的refresh()方法,將資料表格的更動載入Entity實例中,若Entity先前有了一些更動操作,則會被覆蓋:
entityManager.refresh(user);
您可以使用EntityManager的flush()方法,強制EntityManager中管理的所有Entity對應的資料表格與Entity的狀態同步:
entityManager.flush();
EntityManager的clear()方法,可以將EntityManager所管理的Entity實例清除,使Entity處於Detached狀態:
entityManager.clear();
每個EntityManager都與一個 Persistence Context 關聯,EntityManager不直接維護Entity,而是將之委托給Persistence Context,Persistence Context中會維護一組Entity實例,每個Entity在Persistence Context為Managed狀態,Entity實例會有Managed、Detached、Removed狀態,這在 Entity 生命週期 中再作進一步的說明。