<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里邊傳參,防注入的那種  回復  更多評論
      

    主站蜘蛛池模板: 91精品国产亚洲爽啪在线影院| 亚洲六月丁香六月婷婷色伊人| 免费h视频在线观看| 亚洲福利电影一区二区?| 日韩a级毛片免费视频| 两个人的视频www免费| 亚洲婷婷在线视频| 一级毛片直播亚洲| 182tv免费观看在线视频| 精品在线视频免费| 亚洲最大黄色网址| 亚洲国产成人久久精品99 | 久视频精品免费观看99| 亚洲Av永久无码精品黑人| 久久亚洲国产欧洲精品一| 午夜一级免费视频| 日本视频免费高清一本18| 亚洲av中文无码乱人伦在线观看| 亚洲va中文字幕无码久久| 国产美女精品视频免费观看| 日韩免费人妻AV无码专区蜜桃 | 免费看的一级毛片| 三年片在线观看免费大全电影| 美女视频黄频a免费观看| 亚洲高清无在码在线电影不卡| 亚洲精品和日本精品| 久久不见久久见免费影院| 老司机69精品成免费视频| 国产精品亚洲天堂| 国产精品亚洲四区在线观看| 亚洲成a人片在线观看无码专区| 国产免费爽爽视频免费可以看| 免费黄色网址网站| 无码国产精品一区二区免费模式 | 四虎国产精品永久免费网址 | 日韩在线观看免费| 中文字幕亚洲免费无线观看日本| 免费观看理论片毛片| 日本免费A级毛一片| 亚洲kkk4444在线观看| 中文字幕亚洲一区二区三区 |