細心!用心!耐心!

          吾非文人,乃市井一俗人也,讀百卷書,跨江河千里,故申城一游; 一兩滴辛酸,三四年學業,五六點粗墨,七八筆買賣,九十道人情。

          BlogJava 聯系 聚合 管理
            1 Posts :: 196 Stories :: 10 Comments :: 0 Trackbacks
          JPA EntityManager詳解(二)
          ★ 提示 ★

          目前JBoss 4.2集成了的Tomcat版本為5.5,但Tomcat 6.0以后的版本中才支持使用注釋,所以如果將本例中Servlet運行在JBoss 4.2中,并不能獲得EntityManagerFactory對象;但在符合J2EE 5.0的服務器中,這樣運行是可以的。

          雖然在目前JBoss 4.2版本中不支持使用注釋,但可以通過另一種方式來獲得應用托管的EntityManager對象。代碼如下所示。

          1. public class TestServlet extends HttpServlet { 
          2.  
          3.     private EntityManagerFactory emf; 
          4.  
          5.     public TestServlet() { 
          6.  
          7.         super(); 
          8.  
          9.     } 
          10.  
          11.     public void doGet(HttpServletRequest request, HttpServletResponse response) 
          12.  
          13.             throws ServletException, IOException { 
          14.  
          15.         doPost(request, response); 
          16.  
          17.     } 
          18.  
          19.     public void doPost(HttpServletRequest request, HttpServletResponse response) 
          20.  
          21.             throws ServletException, IOException { 
          22.  
          23.         response.setContentType("text/html"); 
          24.  
          25.         PrintWriter out = response.getWriter(); 
          26.  
          27.         out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional //EN\">"); 
          28.  
          29.         out.println("<HTML>"); 
          30.  
          31.         out.println("  <HEAD><TITLE>A Servlet</TITLE></HEAD>"); 
          32.  
          33.         out.println("  <BODY>"); 
          34.  
          35.         if (emf != null) { 
          36.  
          37.             /**創建EntityManager 對象*/ 
          38.  
          39.             EntityManager entityManager = emf.createEntityManager(); 
          40.  
          41.             try { 
          42.  
          43.                 Query query = entityManager 
          44.  
          45.                         .createQuery("SELECT c FROM CustomerEO c"); 
          46.  
          47.                 List<CustomerEO> result = query.getResultList(); 
          48.  
          49.                 for (CustomerEO c : result) { 
          50.  
          51.                     System.out.println(c.getId() + "," + c.getName()); 
          52.  
          53.                 } 
          54.  
          55.             } finally { 
          56.  
          57.                 /**關閉EntityManager*/ 
          58.  
          59.                 entityManager.close(); 
          60.  
          61.             } 
          62.  
          63.         } 
          64.  
          65.         out.println("  </BODY>"); 
          66.  
          67.         out.println("</HTML>"); 
          68.  
          69.         out.flush(); 
          70.  
          71.         out.close(); 
          72.  
          73.     } 
          74.  
          75.     /**Servlet初始化時,創建EntityManagerFactory 對象*/ 
          76.  
          77.     public void init() throws ServletException { 
          78.  
          79.         if (emf == null) { 
          80.  
          81.             emf = Persistence.createEntityManagerFactory("jpaUnit"); 
          82.  
          83.         } 
          84.  
          85.     } 
          86.  
          87.     /**Servlet銷毀時,關閉EntityManagerFactory對象*/ 
          88.  
          89.     public void destroy() { 
          90.  
          91.         if (emf.isOpen()) 
          92.  
          93.             emf.close(); 
          94.  
          95.     } 
          96.  
          97. } 

          public class TestServlet extends HttpServlet {

          private EntityManagerFactory emf;

          public TestServlet() {

          super();

          }

          public void doGet(HttpServletRequest request, HttpServletResponse response)

          throws ServletException, IOException {

          doPost(request, response);

          }

          public void doPost(HttpServletRequest request, HttpServletResponse response)

          throws ServletException, IOException {

          response.setContentType("text/html");

          PrintWriter out = response.getWriter();

          out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional //EN\">");

          out.println("<HTML>");

          out.println("  <HEAD><TITLE>A Servlet</TITLE></HEAD>");

          out.println("  <BODY>");

          if (emf != null) {

          /**創建EntityManager 對象*/

          EntityManager entityManager = emf.createEntityManager();

          try {

          Query query = entityManager

          .createQuery("SELECT c FROM CustomerEO c");

          List<CustomerEO> result = query.getResultList();

          for (CustomerEO c : result) {

          System.out.println(c.getId() + "," + c.getName());

          }

          } finally {

          /**關閉EntityManager*/

          entityManager.close();

          }

          }

          out.println("  </BODY>");

          out.println("</HTML>");

          out.flush();

          out.close();

          }

          /**Servlet初始化時,創建EntityManagerFactory 對象*/

          public void init() throws ServletException {

          if (emf == null) {

          emf = Persistence.createEntityManagerFactory("jpaUnit");

          }

          }

          /**Servlet銷毀時,關閉EntityManagerFactory對象*/

          public void destroy() {

          if (emf.isOpen())

          emf.close();

          }

          }



          使用這種方式創建EntityManagerFactory對象需要注意以下幾個問題。

          可以看到,這里的EntityManagerFactory對象不是通過注入獲得的,而是通過Persistence類中的靜態方法createEntityManagerFactory來創建的。

          — 正因為EntityManagerFactory對象是手動創建的,所以在不再使用時,一定要調用close()方法手動關閉。

          11.1.4.3  J2SE環境中獲得

          在J2SE環境中,獲得應用托管的EntityManager對象只能通過手動創建的方式,而不能使用注釋的方式,與Web容器中不使用注釋的方法相同,都是通過Persistence類中createEntityManagerFactory來創建的。

          例如,下面代碼為J2SE環境中獲得應用托管EntityManager對象的方法。

          1. public class CustomerClient { 
          2.  
          3.     public static void main(String[] args) { 
          4.  
          5.         /** 創建EntityManagerFactory對象 */ 
          6.  
          7.         EntityManagerFactory emf = Persistence 
          8.  
          9.                 .createEntityManagerFactory("jpaUnit"); 
          10.  
          11.         /** 創建entityManager對象 */ 
          12.  
          13.         EntityManager entityManager = emf.createEntityManager(); 
          14.  
          15.         Query query = entityManager.createQuery("SELECT c FROM CustomerEO c"); 
          16.  
          17.         List<CustomerEO> result = query.getResultList(); 
          18.  
          19.         for (CustomerEO c : result) { 
          20.  
          21.             System.out.println(c.getId() + "," + c.getName()); 
          22.  
          23.         } 
          24.  
          25.         /** 關閉entityManager對象 */ 
          26.  
          27.         entityManager.close(); 
          28.  
          29.         /** 關閉EntityManagerFactory對象 */ 
          30.  
          31.         emf.close(); 
          32.  
          33.     } 
          34.  
          35. } 

          public class CustomerClient {

          public static void main(String[] args) {

          /** 創建EntityManagerFactory對象 */

          EntityManagerFactory emf = Persistence

          .createEntityManagerFactory("jpaUnit");

          /** 創建entityManager對象 */

          EntityManager entityManager = emf.createEntityManager();

          Query query = entityManager.createQuery("SELECT c FROM CustomerEO c");

          List<CustomerEO> result = query.getResultList();

          for (CustomerEO c : result) {

          System.out.println(c.getId() + "," + c.getName());

          }

          /** 關閉entityManager對象 */

          entityManager.close();

          /** 關閉EntityManagerFactory對象 */

          emf.close();

          }

          }


          但是,在J2SE環境中使用JPA需要將實現的JPA的第三方類包和數據庫的驅動包,設置到當前的運行環境下。

          例如,在Eclipse中創建一個Java項目,需要將JPA實現者的類庫(這里以Hibernate為例)和MySQL的數據庫連接包添加到構建路徑中,如圖11-2所示。

          11.1.5  ThreadLocal的使用

          對于在Web容器中使用EntityManager對象,這里需要做一些改進,才能更安全。讀者應該了解,Servlet是非線程安全的,所以需要改變獲得EntityManager對象的方式,這里筆者建議使用ThreadLocal類。

          ThreadLocal就是為每一個使用某變量的線程都提供一個該變量值的副本,使每一個線程都可以獨立地改變自己的副本,而不會和其他線程的副本沖突。從線程的角度看,就好像每一個線程都完全擁有一個該變量,這就解決了Servlet非線程安全的問題。

          首先編寫一個EntityManagerHelper類,代碼如下所示。

          1. public class EntityManagerHelper { 
          2.  
          3.     
          4.  
          5.     private static final EntityManagerFactory emf; 
          6.  
          7.     private static final ThreadLocal<EntityManager> threadLocal; 
          8.  
          9.     
          10.  
          11.     /**初始化*/ 
          12.  
          13.     static { 
          14.  
          15.         emf = Persistence.createEntityManagerFactory("jpaUnit");        
          16.  
          17.         threadLocal = new ThreadLocal<EntityManager>(); 
          18.  
          19.     } 
          20.  
          21.     
          22.  
          23.     /**通過threadLocal 獲得EntityManager 對象*/ 
          24.  
          25.     public static EntityManager getEntityManager() { 
          26.  
          27.         EntityManager manager = threadLocal.get();      
          28.  
          29.         if (manager == null || !manager.isOpen()) { 
          30.  
          31.             manager = emf.createEntityManager(); 
          32.  
          33.             threadLocal.set(manager); 
          34.  
          35.         } 
          36.  
          37.         return manager; 
          38.  
          39.     } 
          40.  
          41.     
          42.  
          43.     /**關閉EntityManager 對象*/ 
          44.  
          45.     public static void closeEntityManager() { 
          46.  
          47.         EntityManager em = threadLocal.get(); 
          48.  
          49.         threadLocal.set(null); 
          50.  
          51.         if (em != null) em.close(); 
          52.  
          53.     } 
          54.  
          55.     
          56.  
          57.     public static void beginTransaction() { 
          58.  
          59.     getEntityManager().getTransaction().begin(); 
          60.  
          61.     } 
          62.  
          63.     
          64.  
          65.     public static void commit() { 
          66.  
          67.     getEntityManager().getTransaction().commit(); 
          68.  
          69.     }  
          70.  
          71.     
          72.  
          73.     public static Query createQuery(String query) { 
          74.  
          75.         return getEntityManager().createQuery(query); 
          76.  
          77.     } 
          78.  
          79.     
          80.  
          81. } 

          public class EntityManagerHelper {



          private static final EntityManagerFactory emf;

          private static final ThreadLocal<EntityManager> threadLocal;



          /**初始化*/

          static {

          emf = Persistence.createEntityManagerFactory("jpaUnit");      

          threadLocal = new ThreadLocal<EntityManager>();

          }



          /**通過threadLocal 獲得EntityManager 對象*/

          public static EntityManager getEntityManager() {

          EntityManager manager = threadLocal.get();    

          if (manager == null || !manager.isOpen()) {

          manager = emf.createEntityManager();

          threadLocal.set(manager);

          }

          return manager;

          }



          /**關閉EntityManager 對象*/

          public static void closeEntityManager() {

          EntityManager em = threadLocal.get();

          threadLocal.set(null);

          if (em != null) em.close();

          }



          public static void beginTransaction() {

          getEntityManager().getTransaction().begin();

          }



          public static void commit() {

          getEntityManager().getTransaction().commit();

          }



          public static Query createQuery(String query) {

          return getEntityManager().createQuery(query);

          }



          }



          這樣經過改進后,在Servlet中創建EntityManager對象的方法修改為如下所示。

          1. public class TestServlet extends HttpServlet { 
          2.  
          3.     public TestServlet() { 
          4.  
          5.         super(); 
          6.  
          7.     } 
          8.  
          9.     public void doPost(HttpServletRequest request, HttpServletResponse response) 
          10.  
          11.             throws ServletException, IOException { 
          12.  
          13.             EntityManager entityManager = EntityManagerHelper.getEntityManager(); 
          14.  
          15.             try { 
          16.  
          17.                 Query query = entityManager 
          18.  
          19.                         .createQuery("SELECT c FROM CustomerEO c"); 
          20.  
          21.                 List<CustomerEO> result = query.getResultList(); 
          22.  
          23.                 for (CustomerEO c : result) { 
          24.  
          25.                     System.out.println(c.getId() + "," + c.getName()); 
          26.  
          27.                 } 
          28.  
          29.             } finally { 
          30.  
          31.                 /**關閉EntityManager*/ 
          32.  
          33.                 EntityManagerHelper.closeEntityManager(); 
          34.  
          35.             } 
          36.  
          37.     } 
          38.  
          39. } 

          posted on 2012-06-15 21:36 張金鵬 閱讀(2646) 評論(0)  編輯  收藏 所屬分類: JPA
          主站蜘蛛池模板: 德昌县| 昌江| 孟州市| 洛宁县| 廉江市| 清流县| 通榆县| 沅陵县| 龙南县| 锡林浩特市| 文昌市| 张家港市| 阿坝| 赤水市| 土默特右旗| 新野县| 皮山县| 监利县| 太谷县| 祁门县| 封开县| 图木舒克市| 义马市| 鹤山市| 镇坪县| 巩留县| 江都市| 新建县| 资源县| 贵州省| 曲水县| 靖远县| 呈贡县| 马公市| 米脂县| 温泉县| 浠水县| 嘉定区| 长顺县| 阳曲县| 云阳县|