日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
Java EE 6引入的JPA 2.0四大新特性詳解

【精選譯文】Java EE 5平臺引入了Java持久化API(Java Persistence API,JPA),它為Java EE和Java SE應(yīng)用程序提供了一個基于POJO的持久化模塊。JPA處理關(guān)系數(shù)據(jù)與Java對象之間的映射,它使對象/關(guān)系(O/R)映射標(biāo)準(zhǔn)化,JPA已經(jīng)被廣泛采用,已經(jīng)成為事實上的O/R持久化企業(yè)標(biāo)準(zhǔn)。

創(chuàng)新互聯(lián)專注于企業(yè)營銷型網(wǎng)站建設(shè)、網(wǎng)站重做改版、弋陽網(wǎng)站定制設(shè)計、自適應(yīng)品牌網(wǎng)站建設(shè)、H5開發(fā)、商城網(wǎng)站開發(fā)、集團公司官網(wǎng)建設(shè)、成都外貿(mào)網(wǎng)站建設(shè)公司、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁設(shè)計等建站業(yè)務(wù),價格優(yōu)惠性價比高,為弋陽等各大城市提供網(wǎng)站開發(fā)制作服務(wù)。

Java EE 6帶來了JPA的最新版本 — JSR 317:Java持久化2.0,JPA 2.0帶來了許多新特性和增強,包括:

1、對象/關(guān)系映射增強;

2、Java持久化查詢語言增強;

3、一種新的基于標(biāo)準(zhǔn)的查詢API;

4、支持悲觀鎖定。

對象/關(guān)系映射增強

JPA 1.0支持集合的映射,但這些集合只能包含實體,JPA 2.0增加了集合映射的基礎(chǔ)數(shù)據(jù)類型,如String和Integer,以及嵌入式對象的集合。JPA中的嵌入式對象是一個不能存在于它自身的對象,而是作為父對象的一部分存在,即它的數(shù)據(jù)不是存在于它自己的表中,而是嵌入在父對象的表中。

JPA 2.0增加了兩個支持新的集合映射的注解:@ElementCollection 和 @CollectionTable。使用@ElementCollection注解指定集合的嵌入式對象,這些集合是獨立存儲在集合表中的,使用@CollectionTable注解指定集合表的詳細(xì)信息,如它包含的列。

下面是一個嵌入式類,表示了車輛的訪問服務(wù),它存儲了訪問的日期,描述和費用,此外,車輛可以配備一或多個可選功能,每個功能是FeatureType類型的一個枚舉值。

 
 
 
  1. public enum FeatureType { AC, CRUISE, PWR, BLUETOOTH, TV, ... }  
  2.  
  3.    @Embeddable 
  4.    public class ServiceVisit {  
  5.        @Temporal(DATE)  
  6.        @Column(name="SVC_DATE")  
  7.        Date serviceDate;  
  8.  
  9.        String workDesc;  
  10.        int cost;  
  11.    }  

枚舉值和嵌入式對象可以在一個表示車輛服務(wù)歷史的實體中使用,如:

 
 
 
  1. @Entity 
  2.    public class Vehicle {  
  3.  
  4.        @Id int vin;  
  5.  
  6.        @ElementCollection 
  7.        @CollectionTable(name="VEH_OPTNS")  
  8.   .    @Column(name="FEAT")  
  9.        Set optionalFeatures;  
  10.  
  11.        @ElementCollection 
  12.        @CollectionTable(name="VEH_SVC")  
  13.        @OrderBy("serviceDate")  
  14.        List serviceHistory;  
  15.        ...  
  16.    }  

#t#Vehicle實體中的第一對注解@ElementCollection 和 @CollectionTable指定FeatureType值存儲在VEH_OPTNS集合表中,第二對注解@ElementCollection 和 @CollectionTable指定ServiceVisit嵌入式對象存儲在VEH_SVC集合表中。

雖然在例子中沒有顯示,@ElementCollection注解有兩個屬性:targetClass 和 fetch。targetClass屬性指定基礎(chǔ)類或嵌入式類的類名,如果字段或?qū)傩允鞘褂梅盒投x的,那這兩個屬性是可選的,上面這個例子就是這樣。Fetch屬性是可選的,它指定集合是延后檢索還是立即檢索,使用javax.persistence.FetchType常量,值分別用LAZY和EAGER,默認(rèn)情況下,集合是延后匹配的。

JPA 2.0中還有其它許多關(guān)于對象/關(guān)系映射的增強,例如,JPA 2.0支持嵌套式嵌入,關(guān)系嵌入和有序列表,也增加了新的注解增強映射功能,通過@Access注解更靈活地支持特定的訪問類型,更多用于實體關(guān)系的映射選項,如對單向一對多關(guān)系的外鍵映射支持,通過@MapsId注解支持派生身份,支持孤體刪除。

#p#

Java持久化查詢語言增強

JPA 1.0定義了一個廣泛的Java持久化查詢語言(非正式簡稱為JPQL。有關(guān)JPQL查詢的缺陷,可參考之前發(fā)布的這篇文章),使用它你可以查詢實體和它們的持久化狀態(tài)。JPA 2.0對JPQL做了大量改進,如現(xiàn)在可以在查詢中使用case表達式。在下面的查詢中,如果雇員的評分為1,則通過乘以1.1對雇員的薪水進行了增長,如果評分為2,則乘以1.05,其它評分則乘以1.01。

 
 
 
  1. UPDATE Employee e  
  2.    SET e.salary =  
  3.       CASE WHEN e.rating = 1 THEN e.salary * 1.1  
  4.            WHEN e.rating = 2 THEN e.salary * 1.05  
  5.            ELSE e.salary * 1.01  
  6.       END 

JPA 2.0也為JPQL增加了大量新的運算符,如NULLIF和COALESCE,當(dāng)數(shù)據(jù)庫使用其它非空數(shù)據(jù)解碼時,NULLIF運算符是非常有用的,使用NULLIF,你可以在查詢中將這些值轉(zhuǎn)換為空值,如果參數(shù)等于NULLIF,NULLIF會返回空值,否則返回第一個參數(shù)的值。

假設(shè)薪水?dāng)?shù)據(jù)保存在employee表中,數(shù)據(jù)類型為整數(shù),卻掉的薪水解碼為-9999,下面的查詢返回薪水的平均值,為了正確地忽略卻掉的薪水,查詢使用NULLIF將-9999轉(zhuǎn)換為空值。

 
 
 
  1. SELECT AVG(NULLIF(e.salary, -99999))  
  2.    FROM Employee e  

COALESCE運算符接收一串參數(shù),從列表中返回第一個非空值,相當(dāng)于下面的case表達式:

 
 
 
  1. CASE WHEN value1 IS NOT NULL THEN value1  
  2.         WHEN value2 IS NOT NULL THEN value2  
  3.         WHEN value3 IS NOT NULL THEN value3  
  4.         ...  
  5.         ELSE NULL 
  6.    END 

假設(shè)employee表包括一個辦公電話號碼和家庭電話號碼列,無電話號碼的列使用空值表示。下面的查詢返回每個雇員的姓名和電話號碼,COALESCE運算符指定查詢返回辦公電話號碼,但如果為空,則返回家庭電話號碼,如果兩者都為空,則返回一個空值。

 
 
 
  1. SELECT Name, COALESCE(e.work_phone, e.home_phone) phone  
  2.    FROM Employee e  

#t#JPA 2.0向JPQL增加的其它運算符是INDEX,TYPE,KEY,VALUE和ENTRY。INDEX運算符指定查詢時的排序順序,TYPE運算符選擇一個實體的類型,將查詢限制到一或多個實體類型,KEY,VALUE和ENTRY運算符是JPA 2.0中的泛化映射功能的一部分。使用KEY運算符提取映射鍵,VALUE運算符提取映射值,ENTRY運算符選擇一個映射實體。

此外,JPA 2.0增加了選擇列表、以及集合值參數(shù)和非多態(tài)查詢中運算符的支持。

#p#

標(biāo)準(zhǔn)的API

JPA 2.0中引入的另一個重要特性是標(biāo)準(zhǔn)的API,利用這個API可以動態(tài)地構(gòu)建基于對象的查詢,本質(zhì)上,這個標(biāo)準(zhǔn)API等價于面向?qū)ο蟮腏PQL,使用它,你可以使用基于對象的方法創(chuàng)建查詢,不再需要JPQL使用的字符串操作。

標(biāo)準(zhǔn)API是基于元模型的,元模型是一個提供了架構(gòu)級關(guān)于持久化單元托管類的元數(shù)據(jù)的抽象模型, 元模型讓你構(gòu)建強類型的查詢,它也允許你瀏覽持久化單元的邏輯結(jié)構(gòu)。

通常,一個注解處理器使用元模型生成靜態(tài)元模型類,這些類提供持久化狀態(tài)和持久化單元托管類的關(guān)系,但你可以對靜態(tài)元模型類編碼。下面是一個實體實例:

 
 
 
  1. @Entity public class Employee {  
  2.      @Id Long Id;  
  3.      String firstName;  
  4.      String lastName;  
  5.      Department dept;  
  6.    }  

下面是對應(yīng)的靜態(tài)元模型類:

 
 
 
  1. import javax.persistence.meta,model.SingularAttribute;  
  2.    import javax.persistence.meta,model.StaticMetamodel;  
  3.  
  4.  
  5.    @Generated("EclipseLink JPA 2.0 Canonical Model Generation" 
  6.    @StaticMetamodel(Employee.class)  
  7.    public class Employee_ {  
  8.      public static volatile SingularAttribute id;  
  9.      public static volatile SingularAttribute firstName;  
  10.      public static volatile SingularAttribute lastName;  
  11.      public static volatile SingularAttribute dept;  
  12.  
  13.    }  

此外,JPA 2.0元模型API允許你動態(tài)訪問元模型,因此當(dāng)你使用標(biāo)準(zhǔn)API時,既可以靜態(tài)訪問元模型類,也可以動態(tài)訪問元模型類。標(biāo)準(zhǔn)API提供了更好的靈活性,既可以使用基于對象的方法,又可以使用基于字符串的方法導(dǎo)航元模型,這意味著你有四種使用標(biāo)準(zhǔn)API的方法:

1、靜態(tài)使用元模型類

2、靜態(tài)使用字符串

3、動態(tài)使用元模型

4、動態(tài)使用字符串

無論你使用哪種方法,通過構(gòu)造一個CriteriaQuery對象定義一個基于標(biāo)準(zhǔn)API的查詢時,使用一個工廠對象CriteriaBuilder構(gòu)造CriteriaQuery,可以從EntityManager 或 EntityManagerFactory類中獲得CriteriaBuilder。下面的代碼構(gòu)造一個CriteriaQuery對象:

 
 
 
  1. EntityManager em = ... ;  
  2.    CriteriaBuilder cb = em.getCriteriaBuilder();  
  3.    CriteriaQuery cq = cb.createQuery(Customer.class);  

注意CriteriaQuery對象是泛型類型,使用CriteriaBuilder 的createQuery方法創(chuàng)建一個CriteriaQuery,并為查詢結(jié)果指定類型。在這個例子中,createQuery 方法的Employee.class參數(shù)指定查詢結(jié)果類型是Employee。CriteriaQuery對象和創(chuàng)建它們的方法是強類型的。

接下來,為CriteriaQuery對象指定一個或多個查詢源,查詢源表示查詢基于的實體。你創(chuàng)建一個查詢源,然后使用AbstractQuery接口的from()方法將其添加到查詢。AbstractQuery接口是眾多接口中的一員,如CriteriaQuery,F(xiàn)rom和root,它們都定義在標(biāo)準(zhǔn)API中。CriteriaQuery接口繼承AbstractQuery接口的屬性。

from()方法的參數(shù)是實體類或EntityType實體的實例,from()方法的結(jié)果是一個Root對象,Root接口擴展From接口,它表示某個查詢的from子句中可能出現(xiàn)的對象。

下面的代碼增加一個查詢源到CriteriaQuery對象:

 
 
 
  1. CriteriaBuilder cb = em.getCriteriaBuilder();  
  2.    CriteriaQuery cq = cb.createQuery(Employee.class);  
  3.    Root emp = cq.from(Employee.class);  

當(dāng)你向CriteriaQuery對象添加一個或多個查詢源后,你訪問元模型,然后構(gòu)造一個查詢表達式,你如何做取決于你是以靜態(tài)方式提交查詢還是以動態(tài)方式提交查詢,以及是使用元模型還是字符串導(dǎo)航元模型。下面是一個使用元模型類靜態(tài)查詢的例子:

 
 
 
  1. cq.select(emp);  
  2.    cq.where(cb.equal(emp.get(Employee_.lastName), "Smith"));  
  3.    TypedQuery query = em.createQuery(cq);  
  4.    List rows = query.getResultList();  

CriteriaQuery接口的select() 和 where()方法指定查詢結(jié)果返回的選擇項目。

注意,你使用EntityManager創(chuàng)建查詢時,可以在輸入中指定一個CriteriaQuery對象,它返回一個TypedQuery,它是JPA 2.0引入javax.persistence.Query接口的一個擴展,TypedQuery接口知道它返回的類型。

在元模型術(shù)語中,Employee_是對應(yīng)于Employee實體類的規(guī)范化元模型類,一個規(guī)范化元模型類遵循JPA 2.0規(guī)范中描述的某些規(guī)則。例如,元模型類的名字來源于托管類,一般都是在托管類名字后面追加一個下劃線“_”。一個規(guī)范化元模型是一個包含靜態(tài)元模型類的元模型,這個靜態(tài)元模型對應(yīng)于實體,映射的超類,以及持久化單元中的嵌入式類。實際上,這個查詢使用了規(guī)范化元模型。下面是一個完整的查詢:

 
 
 
  1. EntityManager em = ... ;  
  2.    CriteriaBuilder cb = em.getCriteriaBuilder();  
  3.    CriteriaQuery cq = cb.createQuery(Employee.class);  
  4.    Root emp = cq.from(Employee.class);  
  5.    cq.select(emp);  
  6.    cq.where(cb.equal(emp.get(Employee_.lastName), "Smith"));  
  7.    TypedQuery query = em.createQuery(cq);  
  8.    List rows = query.getResultList();  

下面是使用元模型API查詢的動態(tài)版本:

 
 
 
  1. EntityManager em = ... ;  
  2.    CriteriaBuilder cb = em.getCriteriaBuilder();  
  3.    CriteriaQuery cq = cb.createQuery(Employee.class);  
  4.    Root emp = cq.from(Employee.class);  
  5.    EntityType emp_ = emp.getModel();  
  6.    cq.select(emp);  
  7.    cq.where(cb.equal(emp.get(emp_.getSingularAttribute("lastName", String.class)),"Smith"));  
  8.    TypedQuery query=em.createQuery(cq);  
  9.    List rows=query.getResultList();  

#t#使用元模型API的標(biāo)準(zhǔn)查詢提供了與使用規(guī)范化元模型相同的類型,但它比基于規(guī)范化元模型的查詢更冗長。

Root的getModel()方法返回根對應(yīng)的元模型實體,它也允許運行時訪問在Employee實體中聲明的持久化屬性。

getSingularAttribute()方法是一個元模型API方法,它返回一個持久化的單值屬性或字段,在這個例子中,它返回值為Smith 的lastName屬性。下面是使用字符串的元數(shù)據(jù)導(dǎo)航查詢的靜態(tài)版本:

 
 
 
  1. EntityManager em = ... ;  
  2.    CriteriaBuilder cb = em.getCriteriaBuilder();  
  3.    CriteriaQuery cq = cb.createQuery(Employee.class);  
  4.    Root emp = cq.from(Employee.class);  
  5.    cq.select(emp);  
  6.    cq.where(cb.equal(emp.get("lastName"), "Smith"));  
  7.    TypedQuery query = em.createQuery(cq);  
  8.    List rows = query.getResultList();  

這個基于字符串的方法要相對容易使用些,但卻失去了元模型具有的類型安全。

#p#

支持悲觀鎖

鎖是處理數(shù)據(jù)庫事務(wù)并發(fā)的一種技術(shù),當(dāng)兩個或更多數(shù)據(jù)庫事務(wù)并發(fā)地訪問相同數(shù)據(jù)時,鎖可以保證同一時間只有一個事務(wù)可以修改數(shù)據(jù)。

鎖的方法通常有兩種:樂觀鎖和悲觀鎖。樂觀鎖認(rèn)為多個并發(fā)事務(wù)之間很少出現(xiàn)沖突,也就是說不會經(jīng)常出現(xiàn)同一時間讀取或修改相同數(shù)據(jù),在樂觀鎖中,其目標(biāo)是讓并發(fā)事務(wù)自由地同時得到處理,而不是發(fā)現(xiàn)或預(yù)防沖突。兩個事務(wù)在同一時刻可以訪問相同的數(shù)據(jù),但為了預(yù)防沖突,需要對數(shù)據(jù)執(zhí)行一次檢查,檢查自上次讀取數(shù)據(jù)以來發(fā)生的任何變化。

悲觀鎖認(rèn)為事務(wù)會經(jīng)常發(fā)生沖突,在悲觀鎖中,讀取數(shù)據(jù)的事務(wù)會鎖定數(shù)據(jù),在前面的事務(wù)提交之前,其它事務(wù)都不能修改數(shù)據(jù)。

JPA 1.0只支持樂觀鎖,你可以使用EntityManager類的lock()方法指定鎖模式的值,可以是READ或WRITE,如:

 
 
 
  1. EntityManager em = ... ;  
  2.    em.lock (p1, READ);  

對于READ鎖模式,JPA實體管理器在事務(wù)提交前都會鎖定實體,檢查實體的版本屬性確定實體自上次被讀取以來是否有更新,如果版本屬性被更新了,實體管理器會拋出一個OptimisticLockException異常,并回滾事務(wù)。

對于WRITE鎖模式,實體管理器執(zhí)行和READ鎖模式相同的樂觀鎖操作,但它也會更新實體的版本列。

JPA 2.0增加了6種新的鎖模式,其中兩個是樂觀鎖。JPA 2.0也允許悲觀鎖,并增加了3種悲觀鎖,第6種鎖模式是無鎖。

下面是新增的兩個樂觀鎖模式:

1、OPTIMISTIC:它和READ鎖模式相同,JPA 2.0仍然支持READ鎖模式,但明確指出在新應(yīng)用程序中推薦使用OPTIMISTIC。

2、OPTIMISTIC_FORCE_INCREMENT:它和WRITE鎖模式相同,JPA 2.0仍然支持WRITE鎖模式,但明確指出在新應(yīng)用程序中推薦使用OPTIMISTIC_FORCE_INCREMENT。

下面是新增的三個悲觀鎖模式:

1、PESSIMISTIC_READ:只要事務(wù)讀實體,實體管理器就鎖定實體,直到事務(wù)完成鎖才會解開,當(dāng)你想使用重復(fù)讀語義查詢數(shù)據(jù)時使用這種鎖模式,換句話說就是,當(dāng)你想確保數(shù)據(jù)在連續(xù)讀期間不被修改,這種鎖模式不會阻礙其它事務(wù)讀取數(shù)據(jù)。

2、PESSIMISTIC_WRITE:只要事務(wù)更新實體,實體管理器就會鎖定實體,這種鎖模式強制嘗試修改實體數(shù)據(jù)的事務(wù)串行化,當(dāng)多個并發(fā)更新事務(wù)出現(xiàn)更新失敗幾率較高時使用這種鎖模式。

3、PESSIMISTIC_FORCE_INCREMENT:當(dāng)事務(wù)讀實體時,實體管理器就鎖定實體,當(dāng)事務(wù)結(jié)束時會增加實體的版本屬性,即使實體沒有修改。

你也可以指定新的鎖模式NONE,在這種情況下表示沒有鎖發(fā)生。

JPA 2.0也提供了多種方法為實體指定鎖模式,你可以使用EntityManager的lock() 和 find()方法指定鎖模式。此外,EntityManager.refresh()方法可以恢復(fù)實體實例的狀態(tài)。

下面的代碼顯示了使用PESSIMISTIC_WRITE鎖模式的悲觀鎖:

 
 
 
  1. // read  
  2.    Part p = em.find(Part.class, pId);  
  3.  
  4.    // lock and refresh before update  
  5.    em.refresh(p, PESSIMISTIC_WRITE);  
  6.    int pAmount = p.getAmount();  
  7.    p.setAmount(pAmount - uCount);  

在這個例子中,它首先讀取一些數(shù)據(jù),然后應(yīng)用PESSIMISTIC_WRITE鎖,在更新數(shù)據(jù)之前調(diào)用EntityManager.refresh()方法,當(dāng)事務(wù)更新實體時,PESSIMISTIC_WRITE鎖鎖定實體,其它事務(wù)就不能更新相同的實體,直到前面的事務(wù)提交。

更多JPA 2.0的新特性

除了前面描述的增強和新特性外,JPA 2.0可以使用Bean驗證自動驗證實體,這意味著你可以在實體上指定一個約束,例如,實體中字段的最大長度為15,當(dāng)實體持久化,更新或移除時自動驗證字段,你可以在persistence.xml配置文件中使用元素指定自動驗證生效的周期。

【譯稿,非經(jīng)授權(quán)請勿轉(zhuǎn)載。合作站點轉(zhuǎn)載請注明原文譯者和出處為,且不得修改原文內(nèi)容?!?/p>

原文:A More Complete Java Persistence API  作者:Ed Ort


當(dāng)前名稱:Java EE 6引入的JPA 2.0四大新特性詳解
本文來源:http://m.5511xx.com/article/dhdpjsh.html