<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    細心!用心!耐心!

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

    BlogJava 聯系 聚合 管理
      1 Posts :: 196 Stories :: 10 Comments :: 0 Trackbacks
    JPA EntityManager詳解(一)
    持久化上下文(Persistence Contexts)的相關知識,內容包括如何從Java EE容器中創建EntityManager對象、如何從Java SE中創建EntityManager對象、持久化上下文與事務(Transction)的關系,以及實體管理器工廠(Entity Manager Factory)的相關內容。
    通過本章的學習,讀者將深入掌握JPA中有關持久化上下文、事務處理的相關知識,從而能夠更加深入地應用JPA。


    11.1 獲得EntityManager對象

    那么如何獲得EntityManager對象呢?這又是JPA中另外一個很重要的問題。


    11.1.1  Java EE環境與J2SE環境

    在詳細講述EntityManager對象之前,讀者首先要分清楚兩個概念,即Java EE環境與J2SE環境。因為在本章后面的學習中要經常提到這兩個概念,所以讀者一定要先理解它們,為以后的學習打好基礎。


    — Java EE環境,包括EJB容器和Web容器。

    (1)Web容器:只運行Web應用的容器,例如Tomcat就是開源的Web容器,它可以運行JSP、Servlet等。

    (2)EJB容器:運行在EJB組件的容器,提供EJB組件的狀態管理、事務管理、線程管理、遠程數據資源訪問、連接管理和安全性管理等系統級服務。例如JBoss為EJB容器和Web容器(Web容器是集成了Tomcat)結合。

    部署在EJB容器中的JAR包都可以認為是運行在EJB容器中。但JBoss中的Web應用,比如war包中的類就不是運行在EJB容器中,而是運行在Web容器中。

    — J2SE環境

    最普通Java運行環境,例如一個HelloWorld的Java程序就是運行在J2SE的環境中,通常使用main入口方法作為程序啟動的觸發。

    如圖11-1所示,它說明了Java EE與J2SE環境的關系。

    11.1.2  兩種類型的EntityManager對象

    根據EntityManager對象的管理方式,可以有以下兩種類型。

    — 容器托管的(container-managed)EntityManager對象

    容器托管的EntityManager對象最簡單,程序員不需要考慮EntityManager連接的釋放,以及事務等復雜的問題,所有這些都交 給容器去管理。容器托管的EntityManager對象必須在EJB容器中運行,而不能在Web容器和J2SE的環境中運行。本書前面講述的 EntityManager對象都是通過注入 @PersistenceContext注釋來獲得的,其實,這種獲得EntityManager對象的方式就是容器托管的。

    — 應用托管的(application-managed)EntityManager對象

    應用托管的EntityManager對象,程序員需要手動地控制它的釋放和連接、手動地控制事務等。但這種獲得應用托管的 EntityManager對象的方式,不僅可以在EJB容器中應用,也可以使 JPA脫離EJB容器,而與任何的Java環境集成,比如說Web容器、J2SE環境等。所以從某種角度上來說,這種方式是JPA能夠獨立于EJB環境運 行的基礎。

    理想狀態下,最好是選用容器托管的EntityManager對象的方式,但在特殊的環境下,還是需要使用應用托管的EntityManager對象這種方式。

    正是因為應用托管的EntityManager對象的連接釋放、事務控制比較復雜,所以在使用時涉及的相關內容比較多,這些內容將在本章后面部分詳細講述,這里讀者應對兩種方式有一個大致的了解,兩種EntityManager對象類型的比較如表11-1所示。

    表11-1  容器托管與應用托管的EntityManager對象對比

    比較內容

    容器托管的(container-managed)EntityManager對象

    應用托管的(application-managed)EntityManager對象

    獲得方式

    兩種方式:1 @PersistenceContex注入 2 JNDI獲得

    EntityManagerFactory創建

    支持事務

    JTA

    JTA、RESOURCE_LOCAL

    運行環境

    EJB容器

    EJB容器、Web容器、J2SE環境

    11.1.3  容器托管的(container-managed)EntityManager對象

    容器托管的EntityManager對象只能運行在EJB容器中。所以可以這樣理解,只有在EJB-JAR包中,才可以獲得容器托管的EntityManager對象,否則只能獲得應用托管的EntityManager對象。

    在EJB容器中獲得EntityManager對象主要有兩種方式,即@PersistenceContext注釋注入和JNDI方式獲得。

    11.1.3.1  通過@PersistenceContext注釋注入

    這種方式獲得EntityManager對象最為常用,例如下面代碼所示。

    1. @Stateless  
    2.   
    3. public class CustomerService implements ICustomerService {  
    4.   
    5.     @PersistenceContext(unitName = "jpaUnit")  
    6.   
    7.     private EntityManager entityManager;  
    8.   
    9.     public List<CustomerEO> findAllCustomers() {  
    10.   
    11.         Query query = entityManager.createQuery("SELECT c FROM CustomerEO c");  
    12.   
    13.         List<CustomerEO> result = query.getResultList();  
    14.   
    15.         for (CustomerEO c : result) {  
    16.   
    17.             System.out.println(c.getId()+","+c.getName());  
    18.   
    19.         }  
    20.   
    21.         return result;  
    22.   
    23.     }  
    24.   
    25. }  


    在使用此種方式創建EntityManager對象時,需要注意以下幾個問題。

    — @PersistenceContext注釋中,其中unitName為persistence.xml文件中<persistence-unit>元素中的屬性“name”的值,表示要初始化哪個持久化單元,如下所示。

    Xml代碼
    1. <persistence>  
    2.   
    3.     <persistence-unit name="jpaUnit" transaction-type="JTA">  
    4.   
    5.     </persistence-unit>  
    6.   
    7. </persistence>  


    — @PersistenceContext注釋中還可以配置其他的設置,它的定義如下所示。

    Java代碼
    1. @Target({TYPE, METHOD, FIELD}) @Retention(RUNTIME)  
    2.   
    3. public @interface PersistenceContext{  
    4.   
    5.     String name() default "";  
    6.   
    7.     String unitName() default "";  
    8.   
    9.     PersistenceContextType type default TRANSACTION;  
    10.   
    11.     PersistenceProperty[] properties() default {};  
    12.   
    13. }  


    — 其中PersistenceContextType可以設置創建EntityManager對象時,持久化上下文的作用范圍,它的意義在于對有狀態的Bean(Stateless Bean)可以跨事務操作實體。它主要有兩種方式,定義如下所示。
    Java代碼
    1. public enum PersistenceContextType {  
    2.   
    3.     TRANSACTION,  
    4.   
    5.     EXTENDED  
    6.   
    7. }  


    默認情況下使用TRANSACTION,有關TRANSACTION方式和EXTENDED方式創建EntityManager對象的異同,將在下文中詳細講述,這里讀者簡單了解一下即可。

    11.1.3.2  通過JNDI的方式獲得

    如果指定了@PersistenceContext注釋中的name值,則設置了持久化上下文的JNDI名稱。通過SessionContext可以創建EntityManager對象。

    例如,下面代碼為通過JNDI方式獲得EntityManager對象。

    1. @Stateless  
    2.   
    3. @PersistenceContext(name="jpa")  
    4.   
    5. public class CustomerService implements ICustomerService {  
    6.   
    7.     @Resource  
    8.   
    9.     SessionContext ctx;  
    10.   
    11.     public List<CustomerEO> findAllCustomers() {  
    12.   
    13.         EntityManager entityManager = (EntityManager) ctx.lookup("jpa");  
    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.         return result;  
    26.   
    27.     }  
    28.   
    29. }  


    11.1.4  應用托管的(application-managed)EntityManager對象

    應用托管的EntityManager對象,不僅可以在Java EE環境中獲得,也可以應用在J2SE的環境中。但無論是在什么情況下獲得的EntityManager對象,都是通過實體管理器工廠 (EntityManagerFactory)對象創建的。所以如何獲得應用托管的EntityManager對象關鍵是 EntityManagerFactory對象如何獲得。

    下面就分別講述在EJB容器、Web容器和J2SE環境中如何獲得EntityManagerFactory對象。

    11.1.4.1  EJB容器中獲得

    在EJB容器中,EntityManagerFactory對象可以通過使用注入@PersistenceUnit注釋獲得,例如下面代碼為在EJB容器中,獲得應用托管的EntityManager對象的方法。

    1. @Stateless  
    2.   
    3. public class CustomerService implements ICustomerService {  
    4.   
    5.     @PersistenceUnit(unitName="jpaUnit")  
    6.   
    7.     private EntityManagerFactory emf;  
    8.   
    9.     public List<CustomerEO> findAllCustomers() {  
    10.   
    11.         /**創建EntityManager對象*/  
    12.   
    13.         EntityManager em = emf.createEntityManager();  
    14.   
    15.         Query query = em.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.         em.close();  
    28.   
    29.         return result;  
    30.   
    31.     }  
    32.   
    33. }  

    通過以上的EntityManager對象代碼,可以總結出以下幾個問題。

    — 應用托管的EntityManager對象,要在代碼中手動地創建和關閉,例如下面代碼所示。

    EntityManager em = emf.createEntityManager();

    /**其他的業務邏輯*/

    em.close();

    這點正是與容器托管的EntityManager對象的最大不同之處。事實上,容器托管的EntityManager對象,它的創建和關閉是由容器負責管理的,所以不需要編寫代碼來控制。

    — 應用托管的EntityManager對象,都是通EntityManagerFactory對象來創建的。在容器中可以通過使用注入@PersistenceUnit注釋的方法實現,它的定義如下所示。

    1. @Target({TYPE, METHOD, FIELD}) @Retention(RUNTIME)  
    2.   
    3. public @interface PersistenceUnit{  
    4.   
    5.     String name() default "";  
    6.   
    7.     String unitName() default "";  
    8.   


    其中,屬性unitName為persistence.xml文件中<persistence-unit>元素中的屬性“name”的值,表示要初始化哪個持久化單元,與@PersistenceContext注釋中unitName屬性相同。

    11.1.4.2  Web容器中獲得

    在Web容器中,EntityManagerFactory對象也可以通過使用注入@PersistenceUnit注釋獲得。例如,下面代碼為在 Servlet中,獲得應用托管的EntityManager對象的方法。 /syntaxhighlighter/clipboard_new.swf">
    1. public class TestServlet extends HttpServlet {  
    2.   
    3.     @PersistenceUnit(unitName = "jpaUnit")  
    4.   
    5.     private EntityManagerFactory emf;  
    6.   
    7.     public TestServlet() {  
    8.   
    9.         super();  
    10.   
    11.     }  
    12.   
    13.     public void doGet(HttpServletRequest request, HttpServletResponse response)  
    14.   
    15.             throws ServletException, IOException {  
    16.   
    17.         doPost(request, response);  
    18.   
    19.     }  
    20.   
    21.     public void doPost(HttpServletRequest request, HttpServletResponse response)  
    22.   
    23.             throws ServletException, IOException {  
    24.   
    25.         response.setContentType("text/html");  
    26.   
    27.         PrintWriter out = response.getWriter();  
    28.   
    29.         out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional //EN\">");  
    30.   
    31.         out.println("<HTML>");  
    32.   
    33.         out.println("  <HEAD><TITLE>A Servlet</TITLE></HEAD>");  
    34.   
    35.         out.println("  <BODY>");  
    36.   
    37.         if (emf != null) {  
    38.   
    39.             /**創建EntityManager 對象*/  
    40.   
    41.             EntityManager entityManager = emf.createEntityManager();  
    42.   
    43.             try {  
    44.   
    45.                 Query query = entityManager  
    46.   
    47.                         .createQuery("SELECT c FROM CustomerEO c");  
    48.   
    49.                 List<CustomerEO> result = query.getResultList();  
    50.   
    51.                 for (CustomerEO c : result) {  
    52.   
    53.                     System.out.println(c.getId() + "," + c.getName());  
    54.   
    55.                 }  
    56.   
    57.             } finally {  
    58.   
    59.                 /**關閉EntityManager*/  
    60.   
    61.                 entityManager.close();  
    62.   
    63.             }  
    64.   
    65.         }  
    66.   
    67.         out.println("  </BODY>");  
    68.   
    69.         out.println("</HTML>");  
    70.   
    71.         out.flush();  
    72.   
    73.         out.close();  
    74.   
    75.     }  
    76.   
    77. }  
    posted on 2012-06-15 21:34 張金鵬 閱讀(56277) 評論(1)  編輯  收藏 所屬分類: JPA

    Feedback

    # re: JPA EntityManager詳解(一) 2016-03-18 13:50 謝謝
    版主,如果利用entityManager進行查詢,如何在sql里邊傳參,防注入的那種  回復  更多評論
      

    主站蜘蛛池模板: 久久久久亚洲精品无码网址| 免费鲁丝片一级在线观看| 免费少妇a级毛片| 亚洲精品伦理熟女国产一区二区 | 一级特黄录像免费播放肥| 又黄又爽的视频免费看| 亚洲国产成人AV网站| 国产免费午夜a无码v视频| 美女被羞羞网站免费下载| 亚洲国产精品无码久久青草| 一级做a爱过程免费视频高清| 亚洲色偷拍区另类无码专区| 国产高清视频免费在线观看| 亚洲日韩激情无码一区| 久久免费精品视频| 亚洲精品福利在线观看| 一个人看www在线高清免费看| 亚洲午夜精品一区二区麻豆| 国产v片免费播放| 波霸在线精品视频免费观看| 亚洲国产精品婷婷久久| 91香蕉成人免费网站| 妇女自拍偷自拍亚洲精品| 国产L精品国产亚洲区久久| 久久久久国产免费| 2020亚洲男人天堂精品| 亚洲精品乱码久久久久久蜜桃| 免费无码又爽又刺激高潮软件 | 24小时免费直播在线观看| 亚洲av无码专区首页| 中文字幕亚洲一区| 久久大香香蕉国产免费网站| 亚洲AV无码一区二区三区在线| 在线看片无码永久免费aⅴ| 青青操视频在线免费观看| 丁香婷婷亚洲六月综合色| MM131亚洲国产美女久久| 50岁老女人的毛片免费观看| 国产亚洲成在线播放va| 亚洲午夜视频在线观看| 国产一级淫片a视频免费观看|