EntityManager 是用來對實體Bean 進行操作的輔助類。他可以用來產生/刪除持久化的實體Bean,通過主鍵查找實體bean,也可以通過EJB3 QL 語言查找滿足條件的實體Bean。實體Bean 被EntityManager 管理時,EntityManager跟蹤他的狀態改變,在任何決定更新實體Bean 的時候便會把發生改變的值同步到數據庫中。當實體Bean 從EntityManager 分離后,他是不受管理的,EntityManager 無法跟蹤他的任何狀態改變。EntityManager 的獲取前面已經介紹過,可以通過@PersistenceContext 注釋由EJB 容器動態注入,例:
@PersistenceContext(unitName="foshanshop") EntityManager em;
// 得到實體管理器 private EntityManager getEntityManager() { return EntityManagerHelper.getEntityManager(); }
EntityManager常用方法:
find(*.class,ID) :若實體Bean不存在,則返回null getReference(*,class,ID) : 若實體Bean不存在,則拋出javax.persistence.EntityNotFoundException,另,不保 證實體Bean 已被初始化
1.Entity的獲取:注意:若*.class不是Entity Bean的話,都會引發IllegalArgumentException
2.persist() :
添加實體Bean
1 // 新增數據 2 public void save(Role entity) { 3 try { 4 EntityManagerHelper.beginTransaction(); 5 getEntityManager().persist(entity); 6 EntityManagerHelper.commit(); 7 } catch (RuntimeException re) { 8 EntityManagerHelper.rollback(); 9 throw re; 10 } 11 }
3.更新實體Bean :
當實體正在被容器管理時,你可以調用實體的set 方法對數據進行修改,在容器決定flush 時,更新的數據才會同步到數據庫。如果你希望修改后的數據實時同步到數據庫,你可以執行EntityManager.flush()方法。
4.merge () :
是在實體Bean 已經脫離了EntityManager 的管理時使用,當容器決定flush 時,數據將會同步到數據庫中,執行em.merge(Object obj)方法時,容器的工作規則:
(1).如果此時容器中已經存在一個受容器管理的具有相同ID 的Object實例,容器將會把參數obj的內容拷貝進這個受管理的實例,merge()方法返回受管理的實例,但參數obj仍然是分離的不受管理的。容器在決定Flush時把實例同步到數據庫中。
(2).容器中不存在具有相同ID 的Object實例。容器根據傳進的obj參數Copy 出一個受容器管理的Object實例,同時merge()方法會返回出這個受管理的實例,但參數obj仍然是分離的不受管理的。容器在決定Flush時把 實例同步到數據庫中。如果傳遞進merge ()方法的參數不是實體Bean,會引發一個IllegalArgumentException
1 // 修改數據 2 public Role update(Role entity) { 3 try { 4 EntityManagerHelper.beginTransaction(); 5 Role result = getEntityManager().merge(entity); 6 EntityManagerHelper.commit(); 7 return result; 8 } catch (RuntimeException re) { 9 EntityManagerHelper.rollback(); 10 throw re; 11 } 12 }
5.Remove() :
刪除對象
1 // 刪除數據 2 public void delete(Role entity) { 3 try { 4 EntityManagerHelper.beginTransaction(); 5 entity = getEntityManager() 6 .getReference(Role.class, entity.getId()); 7 getEntityManager().remove(entity); 8 EntityManagerHelper.commit(); 9 } catch (RuntimeException re) { 10 EntityManagerHelper.rollback(); 11 throw re; 12 } 13 }
6.createQuery()
返回Query對象,以執行JPQL語句
7.createNativeQuery()
返回Query對象,以執行SQL語句
8.refresh()
刷新實體Bean,以得到對新對象 (幽雅的獲取最新對象方法)
9.contains()
檢測實體當前是否被管理中該方法使用一個實體作為參數,如果這個實體對象當前正被持久化內容管理,返回值為true,否則為false
10.clear()
分離所有當前正在被管理的實體在處理大量實體的時候,如果你不把已經處理過的實體從EntityManager 中分離出來,將會消耗你大量的內存。調用EntityManager 的clear()方法后,所有正在被管理的實體將會從持久化內容中分離出來。
有一點需要說明下,在事務沒有提交前(事務默認在調用堆棧的最后提交,如:方法的返回),如果調用clear()方法,之前對實體所作的任何改變將會掉失,所以建議你在調用clear()方法之前先調用flush()方法保存更改
11. flush()
將實體的改變立刻刷新到數據庫中
當實體管理器對象在一個session bean 中使用時,它是和服務器的事務上下文綁定的。實體管理器在服務器的事務提交時提交並且同步它的內容。在一個session bean 中,服務器的事務默認地會在調用堆棧的最后提交(如:方法的返回)
12.javax.persistence.FlushModeType 實體Bean管理器的Flush模式
FlushModeType.COMMIT :刷新只有在事務提交時才發生,使用場合:在大量更新數據的過程中存在查詢語句(除了find()和getreference()查詢)的執行
FlushModeType.AUTO :(默認模式)刷新在查詢語句執行前(除了find()和getreference()查詢)或事務提交時才發 生,使用場合:在大量更新數據的過程中沒有任何查詢語句(除了find()和getreference()查詢)的執行。
JDBC 驅動跟數據庫交互的次數。JDBC 性能最大的增進是減少JDBC 驅動與數據庫之間的網絡通訊FlushModeType.COMMIT 模式使更新只在一次的網絡交互中完成,而FlushModeType.AUTO 模式可能需要多次交互(觸發了多少次Flush 就產生了多少次網絡交互)
設置:entityManager.setFlushMode(FlushModeType.COMMIT);
13.getDelegate( )
獲取持久化實現者的引用
用過getDelegate( )方法,你可以獲取EntityManager 持久化實現者的引用,如Jboss EJB3 的持久化產品采用Hibernate,可以通過getDelegate( ) 方法獲取對他的訪問,如:
@PersistenceContext
protected EntityManager em;
HibernateEntityManager manager = (HibernateEntityManager)em.getDelegate();
獲得對Hibernate 的引用后,可以直接面對Hibernate 進行編碼,不過這種方法並不可取,強烈建議不要使用.在Weblogic 中,你也可以通過此方法獲取對Kodo 的訪問
另:映射的表名或列名與數據庫保留字同名時的處理
將表名加標式符,例如:在Mysql下,用'order',或在sqlserver下用[TableName],但這樣做不適合程序移植
1 // 通過id查詢數據 2 public Role findById(Integer id) { 3 try { 4 Role instance = getEntityManager().find(Role.class, id); 5 return instance; 6 } catch (RuntimeException re) { 7 throw re; 8 } 9 } 10 11 // 查詢所有數據 12 @SuppressWarnings("unchecked") 13 public List<Role> findAll() { 14 try { 15 final String queryString = "select model from Role model"; 16 Query query = getEntityManager().createQuery(queryString).setHint( 17 "toplink.refresh", true); 18 return query.getResultList(); 19 } catch (RuntimeException re) { 20 throw re; 21 } 22 }
1 public class EntityManagerHelper { 2 // 實體化私有靜態實體管理器變量emf 3 private staticfinal EntityManagerFactory emf; 4 // 實體化私有靜態本地線程變量threadLocal 5 private staticfinal ThreadLocal<EntityManager> threadLocal; 6 // 用來給兩個變量賦初值的靜態塊 7 static { 8 emf = Persistence.createEntityManagerFactory("lamsPU"); 9 threadLocal = new ThreadLocal<EntityManager>(); 10 } 11 // 得到實體管理器的方法 12 public static EntityManager getEntityManager() { 13 EntityManager manager = threadLocal.get(); 14 if (manager == null || !manager.isOpen()) { 15 manager = emf.createEntityManager(); 16 threadLocal.set(manager); 17 } 18 return manager; 19 } 20 // 關閉實體管理器的方法 21 public staticvoid closeEntityManager() { 22 EntityManager em = threadLocal.get(); 23 threadLocal.set(null); 24 if (em != null) 25 em.close(); 26 } 27 // 開始事務的方法 28 public staticvoid beginTransaction() { 29 getEntityManager().getTransaction().begin(); 30 } 31 // 提交事務的方法 32 public staticvoid commit() { 33 getEntityManager().getTransaction().commit(); 34 } 35 // 回滾事務的方法 36 public staticvoid rollback() { 37 getEntityManager().getTransaction().rollback(); 38 } 39 // 生成查找的方法 40 public static Query createQuery(String query) { 41 return getEntityManager().createQuery(query); 42 } 43 public staticvoid log(String string, Level info, Object object) 44 { 45 // TODO Auto-generated method stub 46 } 47 }
1.Entity的獲取:
注意:若*.class不是Entity Bean的話,都會引發IllegalArgumentException
2.persist() :
添加實體Bean
3.更新實體Bean :
當實體正在被容器管理時,你可以調用實體的set 方法對數據進行修改,在容器決定flush 時,更新的數據才會同步到數據庫。如果你希望修改后的數據實時同步到數據庫,你可以執行EntityManager.flush()方法。
4.merge () :
是在實體Bean 已經脫離了EntityManager 的管理時使用,當容器決定flush 時,數據將會同步到數據庫中,執行em.merge(Object obj)方法時,容器的工作規則:
(1).如果此時容器中已經存在一個受容器管理的具有相同ID 的Object實例,容器將會把參數obj的內容拷貝進這個受管理的實例,merge()方法返回受管理的實例,但參數obj仍然是分離的不受管理的。容器在決定Flush時把實例同步到數據庫中。
(2).容器中不存在具有相同ID 的Object實例。容器根據傳進的obj參數Copy 出一個受容器管理的Object實例,同時merge()方法會返回出這個受管理的實例,但參數obj仍然是分離的不受管理的。容器在決定Flush時把 實例同步到數據庫中。如果傳遞進merge ()方法的參數不是實體Bean,會引發一個IllegalArgumentException
5.Remove() :
刪除對象
6.createQuery()
返回Query對象,以執行JPQL語句
7.createNativeQuery()
返回Query對象,以執行SQL語句
8.refresh()
刷新實體Bean,以得到對新對象 (幽雅的獲取最新對象方法)
9.contains()
檢測實體當前是否被管理中該方法使用一個實體作為參數,如果這個實體對象當前正被持久化內容管理,返回值為true,否則為false
10.clear()
分離所有當前正在被管理的實體在處理大量實體的時候,如果你不把已經處理過的實體從EntityManager 中分離出來,將會消耗你大量的內存。調用EntityManager 的clear()方法后,所有正在被管理的實體將會從持久化內容中分離出來。
有一點需要說明下,在事務沒有提交前(事務默認在調用堆棧的最后提交,如:方法的返回),如果調用clear()方法,之前對實體所作的任何改變將會掉失,所以建議你在調用clear()方法之前先調用flush()方法保存更改
11. flush()
將實體的改變立刻刷新到數據庫中
當實體管理器對象在一個session bean 中使用時,它是和服務器的事務上下文綁定的。實體管理器在服務器的事務提交時提交並且同步它的內容。在一個session bean 中,服務器的事務默認地會在調用堆棧的最后提交(如:方法的返回)
12.javax.persistence.FlushModeType 實體Bean管理器的Flush模式
FlushModeType.COMMIT :刷新只有在事務提交時才發生,使用場合:在大量更新數據的過程中存在查詢語句(除了find()和getreference()查詢)的執行
FlushModeType.AUTO :(默認模式)刷新在查詢語句執行前(除了find()和getreference()查詢)或事務提交時才發 生,使用場合:在大量更新數據的過程中沒有任何查詢語句(除了find()和getreference()查詢)的執行。
JDBC 驅動跟數據庫交互的次數。JDBC 性能最大的增進是減少JDBC 驅動與數據庫之間的網絡通訊FlushModeType.COMMIT 模式使更新只在一次的網絡交互中完成,而FlushModeType.AUTO 模式可能需要多次交互(觸發了多少次Flush 就產生了多少次網絡交互)
設置:entityManager.setFlushMode(FlushModeType.COMMIT);
13.getDelegate( )
獲取持久化實現者的引用
用過getDelegate( )方法,你可以獲取EntityManager 持久化實現者的引用,如Jboss EJB3 的持久化產品采用Hibernate,可以通過getDelegate( ) 方法獲取對他的訪問,如:
@PersistenceContext
protected EntityManager em;
HibernateEntityManager manager = (HibernateEntityManager)em.getDelegate();
獲得對Hibernate 的引用后,可以直接面對Hibernate 進行編碼,不過這種方法並不可取,強烈建議不要使用.在Weblogic 中,你也可以通過此方法獲取對Kodo 的訪問
另:映射的表名或列名與數據庫保留字同名時的處理
將表名加標式符,例如:在Mysql下,用'order',或在sqlserver下用[TableName],但這樣做不適合程序移植
[java] view plain copy