JPA開(kāi)發(fā)文檔大全_第1頁(yè)
JPA開(kāi)發(fā)文檔大全_第2頁(yè)
JPA開(kāi)發(fā)文檔大全_第3頁(yè)
JPA開(kāi)發(fā)文檔大全_第4頁(yè)
JPA開(kāi)發(fā)文檔大全_第5頁(yè)
已閱讀5頁(yè),還剩20頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、 JPA開(kāi)發(fā)文檔(大全)這是一份比較全面的JPA文檔,希望能夠幫助大家,讓大家更好的學(xué)習(xí)工作。 1.發(fā)展中的持久化技術(shù)31.1 JDBC31.2 關(guān)系對(duì)象映射(Object Relational Mapping,ORM)31.3 Java 數(shù)據(jù)對(duì)象(Java Data Object,JDO)31.4 Java Persistence API(JPA)32.JPA 體系架構(gòu)53.Entity Bean73.1定義對(duì)Entity中屬性變量的訪問(wèn)73.2 主鍵和實(shí)體標(biāo)識(shí)(Primary Key and Entity Identity)94.EntityManager104.1 配

2、置和獲得EntityManager104.2 Entity的生命周期和狀態(tài)104.3 持久化Entity(Persist)114.4 獲取Entity134.5 更新Entity134.6 刪除Entity134.7 脫離/附合(Detach/Merge)145.JPA Query145.1 Query接口155.2 簡(jiǎn)單查詢155.3 使用參數(shù)查詢165.4 排序(order by)165.5 查詢部分屬性175.6 查詢中使用構(gòu)造器(Constructor)175.7 聚合查詢(Aggregation)185.8 關(guān)聯(lián)(join)195.9比較Entity205.10 批量更新(Batch

3、 Update)215.11批量刪除(Batch Remove)211.     發(fā)展中的持久化技術(shù)1.1 JDBC很多企業(yè)應(yīng)用的開(kāi)發(fā)者選擇使用 JDBC 管理關(guān)系型數(shù)據(jù)庫(kù)中的數(shù)據(jù)。JDBC支持處理大量的數(shù)據(jù),能夠保證數(shù)據(jù)的一致性,支持信息的并發(fā)訪問(wèn),提供 SQL 查詢語(yǔ)言查找數(shù)據(jù)。JDBC 所使用的關(guān)系模型不是為保存對(duì)象而設(shè)計(jì)的,因此迫使開(kāi)發(fā)者選擇在處理持久數(shù)據(jù)時(shí)放棄面向?qū)ο缶幊?,或者自己去開(kāi)發(fā)將面向?qū)ο筇匦裕ū热纾侯愔g的繼承)和關(guān)系型數(shù)據(jù)庫(kù)進(jìn)行映射的專有解決方案。1.2 關(guān)系對(duì)象映射(Object Relational Mapping,ORM)OR

4、M 是目前完成對(duì)象和關(guān)系數(shù)據(jù)表之間的映射最好的一種技術(shù), 這些 ORM 框架處理對(duì)象和關(guān)系數(shù)據(jù)庫(kù)之間的協(xié)調(diào)工作,將開(kāi)發(fā)者從這部分工作中解脫出來(lái),集中精力處理對(duì)象模型。阻礙 ORM 發(fā)展的問(wèn)題是,現(xiàn)有的每一種 ORM 產(chǎn)品都有自己特有的 API,開(kāi)發(fā)者只能將自己的代碼綁定到某一個(gè)框架提供商的接口上,這種狀況形成了廠商鎖定,意味著一旦該框架提供商無(wú)法解決系統(tǒng)中出現(xiàn)的嚴(yán)重錯(cuò)誤,或者因?yàn)槠渌脑蜣D(zhuǎn)而采用其它的框架,將會(huì)給開(kāi)發(fā)者的企業(yè)應(yīng)用帶來(lái)極大的困難,唯一的解決辦法是重寫所有的持久化代碼。1.3 Java 數(shù)據(jù)對(duì)象(Java Data Object,JDO)JDO 是 Java EE 標(biāo)準(zhǔn)中另外一個(gè)

5、支持管理持久化數(shù)據(jù)的規(guī)范,JDO 規(guī)范使用和 JPA 非常類似的 API,只是通常是通過(guò) JCA 技術(shù)集成到應(yīng)用服務(wù)器上。但是 JDO 是針對(duì)輕量級(jí)容器而設(shè)計(jì)的,不能夠支持容器級(jí)別的聲明式安全、事務(wù)特性,也無(wú)法對(duì)遠(yuǎn)程方法調(diào)用提供支持。1.4 Java Persistence API(JPA)EJB 3.0 規(guī)范由三部分組成:EJB3.0 Simplified API、EJB 核心規(guī)范(EJB Core Contracts and Requirements)和 JPA(Java Persistence API)。JPA 規(guī)范部分詳細(xì)的介紹了 JPA 中實(shí)體 Bean 的定義,并介紹了實(shí)體 Bea

6、n 支持的注釋、全新的查詢語(yǔ)言、實(shí)體管理接口、容器實(shí)現(xiàn)規(guī)范等內(nèi)容。JPA 標(biāo)準(zhǔn)制定過(guò)程中充分吸收了目前已經(jīng)出現(xiàn)的所有持久化技術(shù)的所有優(yōu)點(diǎn),摒棄了它們存在的局限,使 JPA 在簡(jiǎn)單易用、查詢能力等方面表現(xiàn)突出。 標(biāo)準(zhǔn)化JPA 是 JCP 組織發(fā)布的 Java EE 標(biāo)準(zhǔn)之一,因此任何聲稱符合 JPA 標(biāo)準(zhǔn)的框架都遵循同樣的架構(gòu),提供相同的訪問(wèn) API,這保證了基于 JPA 開(kāi)發(fā)的企業(yè)應(yīng)用能夠經(jīng)過(guò)少量的修改就能夠在不同的 JPA 框架下運(yùn)行。 對(duì)容器級(jí)特性的支持JPA 框架中支持大數(shù)據(jù)集、事務(wù)、并發(fā)等容器級(jí)事務(wù),這使得 JPA 超越了簡(jiǎn)單持久化框架的局限,在企業(yè)應(yīng)用發(fā)揮更大的作

7、用。 簡(jiǎn)單易用,集成方便JPA 的主要目標(biāo)之一就是提供更加簡(jiǎn)單的編程模型:在 JPA 框架下創(chuàng)建實(shí)體和創(chuàng)建 Java 類一樣簡(jiǎn)單,沒(méi)有任何的約束和限制,只需要使用 進(jìn)行注釋;JPA 的框架和接口也都非常簡(jiǎn)單,沒(méi)有太多特別的規(guī)則和設(shè)計(jì)模式的要求,開(kāi)發(fā)者可以很容易的掌握。JPA 基于非侵入式原則設(shè)計(jì),因此可以很容易的和其它框架或者容器集成。 可媲美 JDBC 的查詢能力JPA 定義了獨(dú)特的 JPQL(Java Persistence Query Language),JPQL 是 EJB QL 的一種擴(kuò)展,它是針對(duì)實(shí)體的一種查詢語(yǔ)言,操作對(duì)象是實(shí)體,而不是關(guān)系數(shù)據(jù)庫(kù)的表,而且能夠

8、支持批量更新和修改、JOIN、GROUP BY、HAVING 等通常只有 SQL 才能夠提供的高級(jí)查詢特性,甚至還能夠支持子查詢。 支持面向?qū)ο蟮母呒?jí)特性JPA 中能夠支持面向?qū)ο蟮母呒?jí)特性,比如類之間的繼承、多態(tài)和類之間的復(fù)雜關(guān)系,這樣的支持能夠讓開(kāi)發(fā)者最大限度的使用面向?qū)ο蟮哪P驮O(shè)計(jì)企業(yè)應(yīng)用,而不需要自行處理這些特性在關(guān)系數(shù)據(jù)庫(kù)的持久化。支持內(nèi)容:JDBCORMJDOEJB 3(JPA)Java 對(duì)象NoYesYesYes高級(jí)OO原理NoYesYesYes事務(wù)完整性YesYesYesYes并發(fā)YesYesYesYes大數(shù)據(jù)集YesYesYesYes現(xiàn)有 SchemaYesYesY

9、esYes關(guān)系型和非關(guān)系型數(shù)據(jù)存儲(chǔ)NoNoYesNo查詢YesYesYesYes嚴(yán)格的標(biāo)準(zhǔn)/可移植NoNoYesYes簡(jiǎn)單易用YesYesYesYes表 1 持久化技術(shù)的優(yōu)缺點(diǎn)2.     JPA 體系架構(gòu)JPA 中定義一套類和接口用于實(shí)現(xiàn)持久化管理和對(duì)象/關(guān)系的映射,下面這張圖中顯示了 JPA 的主要組件以及它們之間的相互關(guān)系。圖1 JPA 主要組件和相互關(guān)系· EntityManagerFactory EntityManagerFactory 是 EntityManager 的工廠類,負(fù)責(zé)創(chuàng)建 EntityManager 對(duì)象。·

10、 EntityManager EntityManager 是 JPA 應(yīng)用中使用的基本對(duì)象,通過(guò)它提供的相應(yīng)方法可以管理持久化對(duì)象,也可以新建或者刪除持久化對(duì)象。EntityManager 還負(fù)責(zé)創(chuàng)建 Query 實(shí)例。在容器外使用時(shí),EntityManagerFactory 和 EntityManager 之間是一對(duì)一的關(guān)系。· Entity EntityTransaction 提供 Entity 操作時(shí)需要的事務(wù)管理,和 EntityManager 是一對(duì)一的關(guān)系。在查詢操作時(shí)不需要使用 EntityTransaction,而在對(duì)象持久化、狀態(tài)更新、對(duì)象刪除等情況下則必須使用顯式

11、的使用 EntityTransaction 的相關(guān)方法管理事務(wù)。· Query Query 是查詢實(shí)體的接口,Query 對(duì)象可以從 EntityManager 中獲得。根據(jù) EJB 3.0 規(guī)范中的描述,Query 接口需要同時(shí)支持 JPQL 和原生態(tài) SQL 兩種語(yǔ)法。· Persistence Persistence 是一個(gè)工具類,負(fù)責(zé)根據(jù)配置文件提供的參數(shù)創(chuàng)建 EntityManagerFactory 對(duì)象。 下面的代碼演示了如何通過(guò) JPA 提供的接口和 JPQL 查詢語(yǔ)言完成實(shí)體查詢和更新的例子,例子中的代碼假定運(yùn)行在非 Java EE 環(huán)境中。

12、60;清單 1 在非 Java EE 環(huán)境使用 JPA 接口的例子EntityManagerFactory factory = Persistence.createEntityManagerFactory (“mysql”);/ 從 EntityManagerFactory 實(shí)例 factory 中獲取 EntityManagerEntityManager em = factory.createEntityManager(PersistenceContextType.EXTENDED); / 實(shí)體的更新需要在事務(wù)中運(yùn)行EntityTransaction tx = em.getTran

13、saction ();tx.begin ();/ 查找所有公司中的女性雇員Query query = em.createQuery ("select e from Employee e where e.sex = 'femail'");List results = query.getResultList ();/ 給所有女性雇員增加半天假期for (Object res : results) Employee emp = (Employee) res; emp.setHoliday (emp.getHoliday () +0.5);/ 提交事務(wù)(持久化所有更

14、新)mit ();em.close ();factory.close (); 下面的代碼顯示了在 EJB 容器中開(kāi)發(fā) JPA 應(yīng)用時(shí)的接口使用情況,由于容器中的 EntityManager 是注入的,事務(wù)也是聲明式的,因此在容器中完成上面的業(yè)務(wù)邏輯要簡(jiǎn)單得多。 清單 2 在容器中運(yùn)行的 JPA 例子/* 在容器中運(yùn)行 JPA 應(yīng)用時(shí),EntityManager 接口的實(shí)例”em”* 是通過(guò) Resource 注釋注入的。事務(wù)也通常是聲明式的。*/ 查找所有公司中的女性雇員Query query = em.createQuery ("select e from Em

15、ployee e where e.sex = 'femail'");List results = query.getResultList (); / 給所有女性雇員增加半天假期for (Object res : results) Employee emp = (Employee) res; emp.setHoliday (emp.getHoliday () +0.5);  3.     Entity BeanEJB3 Entity可以是很簡(jiǎn)單的java bean,只要批注了Entity或者在xml配

16、置中作了說(shuō)明,就被做一個(gè)可持久化的Entity處理。 但還是需要遵行一定的規(guī)則:·         Entity類必須要有一個(gè)無(wú)參數(shù)的public或者protected的Constructor。 ·         如果在應(yīng)用中需要將該Entity類分離出來(lái)在分布式環(huán)境中作為參數(shù)傳遞,該Entity Class需要實(shí)現(xiàn)接口。 ·      

17、0;  Entity類不可以是final,也不可有final的方法。 ·         abstract類和Concrete實(shí)體類都可以作為Entity類。 ·         Entity類中的屬性變量不可以是public。Entity類的屬性必須通過(guò)getter/setter或者其他的商業(yè)方法獲得。3.1定義對(duì)Entity中屬性變量的訪問(wèn)在絕大部分的商業(yè)應(yīng)用,開(kāi)發(fā)人員都可以忽略這部分無(wú)需關(guān)心。但如果你

18、需要編寫復(fù)雜的Entity類的話,你需要了解這個(gè)部分。復(fù)雜的Entity類是指在Entity類的getter/setter和商業(yè)方法中包含比較復(fù)雜的業(yè)務(wù)邏輯而不是僅僅返回/符值某個(gè)屬性。在大部分的情況下,我們都建議使Entity類中setter/getter中的邏輯盡可能簡(jiǎn)單,除了必要的校驗(yàn)符值外,不要包含復(fù)雜的業(yè)務(wù)邏輯,例如對(duì)關(guān)聯(lián)的其他Entity類進(jìn)行操作。但有些情況下,我們還是需要在Entity類的setter/getter方法中包含商業(yè)邏輯。這時(shí)候,采用何種屬性訪問(wèn)方式就可能會(huì)影響代碼的性能甚至是邏輯正確產(chǎn)生影響。EJB3持久化規(guī)范中,在默認(rèn)情況下所有的屬性都會(huì)自動(dòng)的被持久化,除非屬性

19、變量用Transient元數(shù)據(jù)進(jìn)行了標(biāo)注。針對(duì)可持久化屬性定義了兩種屬性訪問(wèn)方式(access): FIELD和PROPERTY。·         如果采用access=FIELD, EJB3 Persistence運(yùn)行環(huán)境直接訪問(wèn)對(duì)象的屬性變量,而不是通過(guò)getter。這種訪問(wèn)方式也不要求每個(gè)屬性必須有g(shù)etter/setter。如果需要在getter中包含商業(yè)邏輯,應(yīng)該采用access=FIELD的方式。 ·       

20、;  如果采用access=PROPERTY, EJB3 Persistence運(yùn)行環(huán)境將通過(guò)Entity類上的getter來(lái)訪問(wèn)對(duì)象的屬性變量,這就要求每個(gè)屬性變量要有g(shù)etter/setter方法。在EJB3中,默認(rèn)的屬性訪問(wèn)方式是PROPERTY。access=PROPERTY時(shí)getter/setter的邏輯應(yīng)該盡量簡(jiǎn)單。 規(guī)范中access方式還有多一層含義。就是采用access=FIELD時(shí),元數(shù)據(jù)應(yīng)該批注在屬性上。 Id(generate=GeneratorType.NONE) private int id; private String foo;  /* *

21、 The entity class must have a no-arg constructor. */ public HelloEntityBean() public int getId() return id;  采用access=PROPERTY(默認(rèn)方式)時(shí),元數(shù)據(jù)應(yīng)該批注在對(duì)應(yīng)屬性變量的getter上。 private int id;private String foo; /* * The entity class must have a no-arg constructor.*/public HelloEntityBean()  Id(generate

22、=GeneratorType.NONE)public int getId() return id; Entity類中的屬性變量可以是以下數(shù)據(jù)類型:· 原始數(shù)據(jù)類型和他們的對(duì)象類型 · java.lang.String · java.math.BigInteger · java.math.BigDecimal · java.util.Date · java.util.Calendar · java.sql.Date · java.sql.Time · java.sql.Timestamp · by

23、te · Byte · char · Character · enums · Entity類 · 嵌入實(shí)體類(embeddable classes) 還可以是以下集合類型:· 和它的實(shí)體類 · 和它的實(shí)體類 · 和它的實(shí)體類 · 和它的實(shí)體類 3.2 主鍵和實(shí)體標(biāo)識(shí)(Primary Key and Entity Identity)每個(gè)Entity類都必須有一個(gè)主鍵。在EJB3中定義了兩種主鍵:鍵單主鍵和復(fù)合主鍵。 簡(jiǎn)單主鍵必須對(duì)應(yīng)Entity中的一個(gè)屬性變量(Instance Variable)

24、,而該屬性對(duì)應(yīng)數(shù)據(jù)庫(kù)表中的一列。使用簡(jiǎn)單主鍵,我們只需要用Id元數(shù)據(jù)對(duì)一個(gè)屬性變量或者她的getter方法進(jìn)行批注。當(dāng)我們需要使用一個(gè)或多個(gè)屬性變量(表中的一列或多列)聯(lián)合起來(lái)作為主鍵,我們需要使用復(fù)合主鍵。復(fù)合主鍵要求我們編寫一個(gè)復(fù)合主鍵類( Composite Primary Key Class )。復(fù)合主鍵類需要符合以下一些要求:·         復(fù)合主鍵類必須是public和具備一個(gè)沒(méi)有參數(shù)的constructor · 復(fù)合主鍵類的每個(gè)屬性變量必須有g(shù)etter/setter,如果沒(méi)有

25、,每個(gè)屬性變量則必須是public或者protected · 復(fù)合主鍵類必須實(shí)現(xiàn)java.io.serializable · 復(fù)合主鍵類必須實(shí)現(xiàn)equals()和hashcode()方法 · 復(fù)合主鍵類中的主鍵屬性變量的名字必須和對(duì)應(yīng)的Entity中主鍵屬性變量的名字相同 · 一旦主鍵值設(shè)定后,不要修改主鍵屬性變量的值 復(fù)合主鍵的例子。Entity類Person,它的主鍵屬性變量是firstName和lastName。 Id private String firstName; Id private String lastName;  publi

26、c Person() Person的復(fù)合主鍵類: public class PersonPK implements java.io.Serializable private String firstName; private String lastName;  public PersonPK()   public String getFirstName() return firstName;   public void setFirstName(String firstName) this.firstName = firstName;   public

27、String getLastName() return lastName;   public void setLastName(String lastName) this.lastName = lastName; 4.     EntityManager對(duì)Entity進(jìn)行操作的API都設(shè)計(jì)在接口上。EntityManager,顧名思義是管理所有EJB 3運(yùn)行環(huán)境中的所有Entity。 EntityManager根據(jù)運(yùn)行的環(huán)境不同分為容器管理的EntityManager和應(yīng)用管理的EntityManager。 4.1 配置和獲得EntityMan

28、ager在J2SE環(huán)境中,EJB3定義了一個(gè)類用于啟動(dòng)EJB3運(yùn)行環(huán)境。要獲得EntityManager,首先需要通過(guò)獲得EntityManagerFactory,然后調(diào)用EntityManagerFactory.createEntityManager()方法獲得。   / 獲得默認(rèn)當(dāng)前的EntityManagerFactory final EntityManagerFactory emf = Persistence.createEntityManagerFactory(); final EntityManager entityManager = emf.createEntityMa

29、nager(); 當(dāng)調(diào)用Persistence.createEntityManagerFactory()的時(shí)候,Persistence會(huì)做以下的步驟:· 搜索當(dāng)前jar包的META-INFO/persistence.xml配置文件 · 如果沒(méi)有在META-INFO下找到persistence.xml,搜索當(dāng)前線程的ContextClassLoader中的persistence.xml · 根據(jù)獲得的persistence.xml初始化EntityManagerFactory 4.2 Entity的生命周期和狀態(tài)在EJB3中定義了四種Entity的狀態(tài): ·

30、; 新實(shí)體(new)。Entity由應(yīng)用產(chǎn)生,和EJB3 Persistence運(yùn)行環(huán)境沒(méi)有聯(lián)系,也沒(méi)有唯一的標(biāo)示符(Identity)。 · 持久化實(shí)體(managed)。新實(shí)體和EJB3 Persistence運(yùn)行環(huán)境產(chǎn)生關(guān)聯(lián)(通過(guò)persist(), merge()等方法),在EJB3 Persistence運(yùn)行環(huán)境中存在和被管理,標(biāo)志是在EJB3 Persistence運(yùn)行環(huán)境中有一個(gè)唯一的標(biāo)示(Identity)。 · 分離的實(shí)體(detached)。Entity有唯一標(biāo)示符,但它的標(biāo)示符不被EJB3 Persistence運(yùn)行環(huán)境管理,同樣的該Entity也不被

31、EJB3 Persistence運(yùn)行環(huán)境管理。 · 刪除的實(shí)體(removed)。Entity被remove()方法刪除,對(duì)應(yīng)的紀(jì)錄將會(huì)在當(dāng)前事務(wù)提交的時(shí)候從數(shù)據(jù)庫(kù)中刪除。 · 圖2 狀態(tài)的轉(zhuǎn)化 4.3 持久化Entity(Persist) final EntityManagerFactory emf = Persistence.createEntityManagerFactory(); final EntityManager entityManager = emf.createEntityManager();  final HelloEntityBean hel

32、lo = new HelloEntityBean( 1, "foo" ); EntityTransaction trans = entityManager.getTransaction(); trans.begin(); / 持久化hello,在此操作之前hello的狀態(tài)為new entityManager.persist( hello ); / 這時(shí)hello的狀態(tài)變?yōu)閙anaged mit();  entityManager.close(); / 這時(shí)hellow的狀態(tài)變?yōu)閐etached. 當(dāng)保存一個(gè)Entity時(shí),以該對(duì)象為根對(duì)象的整個(gè)對(duì)象圖都會(huì)自動(dòng)的被保

33、存。但在EJB3中,我們?nèi)匀豢梢酝ㄟ^(guò)關(guān)系元數(shù)據(jù)(比如OneToOne,OneToMany)的cascade屬性來(lái)精確定義保存的級(jí)聯(lián)行為。 下面我們來(lái)看看不同的cascade屬性的區(qū)別。 不配置cascade的情況下,EJB3 Persistence運(yùn)行環(huán)境默認(rèn)不會(huì)采用Persistence by reachability。 public class Father Id int id String name; / OneToOne沒(méi)有配置cascade屬性,因此默認(rèn)不會(huì)使用Persistence by reachablity OneToOne Son mySon public Father( i

34、nt id, String name, Son mySon ) this.id = id; = name; this.mySon = mySon; 現(xiàn)在來(lái)保存一個(gè)Father和Son。 final EntityManager manager = emf.createEntityManager(); manager.getTransaction().begin; Son mySon = new Son(); Father = new Father( 1, "father" mySon ); / 保存Father manager.persist( fathe

35、r ); / 由于OneToOne關(guān)系中沒(méi)有配置casacade屬性,father 關(guān)聯(lián)的mySon不會(huì)被自動(dòng)保存,需要分別保存 manager.persist( mySon ); manager.getTransaction().commit(); manager.close(); 現(xiàn)在我們配置casacde=CascadeType.ALL public class Father Id int id String name; / OneToOne配置cascade=CascadeType.ALL,配置cascade=CascadeType.PERSIT也對(duì)persist操作也可以獲得同樣的效

36、果。 / CascadeType.ALL包含CascadeType.PERSIST。 OneToOne(cascade=CascadeType.ALL) Son mySon public Father( int id, String name, Son mySon ) this.id = id; this.mySon = mySon; = name; 在代碼中同樣持久化Father和mySon。 final EntityManager manager = emf.createEntityManager(); manager.getTransaction().begin; S

37、on mySon = new Son(); Father = new Father( 1, mySon ); / 保存Father。由于OneToOne關(guān)系中配置casacade=CascadeType.ALL屬性,關(guān)聯(lián)的mySon會(huì)自動(dòng)地被持久化 manager.persist( father ); manager.getTransaction().commit(); manager.close(); 建議在應(yīng)用中盡可能使用cascade=CascadeType.ALL來(lái)減少持久化操作的復(fù)雜性和代碼量,特別是在有復(fù)雜對(duì)象關(guān)系圖的時(shí)候。 4.4 獲取Entity如果知道Entity的唯一標(biāo)示符

38、,我們可以用find()方法來(lái)獲得Entity。 Father father = manager.find( Father.class, new Integer( 1 ) ); / 由于JDK1.5支持自動(dòng)轉(zhuǎn)型,也可以如下使用 Father father = manager.find( Father.class, 1 ); /* *或者,可以用Entity名字作為查找。但無(wú)法利用JDK 1.5的自動(dòng)轉(zhuǎn)型功能, * 需要使用對(duì)象作為查找主鍵,并需要對(duì)獲得Entity進(jìn)行轉(zhuǎn)型 */ Father father = (Father)manager.find( "com.redsoft.sa

39、mples.Father", new Integer( 1 ) ); 4.5 更新Entity對(duì)Entity的更新必須在事物內(nèi)完成。和persist中一樣,關(guān)系元數(shù)據(jù)的cascade屬性對(duì)是否集聯(lián)刪除有影響。 transaction.begin(); Father father = manager.find( Father.class, 1 ); / 更新原始數(shù)據(jù)類型 father.setName( "newName" ); / 更新對(duì)象引用 Son newSon = new Son(); father.setSon( newSon ); / 提交事務(wù),剛才的更新

40、同步到數(shù)據(jù)庫(kù) mit(); 4.6 刪除Entity對(duì)Entity的刪除必須在事物內(nèi)完成。 transaction.begin(); Father father = manager.find( Father.class, 1 ); / 如果father/son的OneToOne的cascade=CascadeType.ALL,在刪除father時(shí)候,也會(huì)把son刪除。 / 把cascade屬性設(shè)為cascade=CascadeType.REMOVE有同樣的效果。 manager.remove( father ); / 提交事務(wù),剛才的更新同步到數(shù)據(jù)庫(kù) mit(); 4.7 脫離/附合(Deta

41、ch/Merge)在三層或者分布式應(yīng)用中,我們很多時(shí)候需要Entity能脫離EntityManager,避免長(zhǎng)時(shí)間保持EntityManager打開(kāi)占用資源和可以在不同的JVM之間傳遞Entity。在脫離EJB3 Persistence Runtime(EntityManager)的管理后,我們?nèi)匀豢梢宰x取或者修改Entity中的內(nèi)容。而在稍后的時(shí)間,我們又可以將Entity重新和原有或者新的EntityManager附合,如果附合前Entity被改動(dòng)過(guò),更改的數(shù)據(jù)可以自動(dòng)的被發(fā)現(xiàn)并和數(shù)據(jù)庫(kù)同步。 EntityManager entityManager = emf.createEntityMa

42、nager(); / 這時(shí)Father還是被EntityManager管理的 Father father = manager.find( Father.class, 1 ); / 當(dāng)entityManger關(guān)閉的時(shí)候,當(dāng)前被entityManager管理的Entity都會(huì)自動(dòng)的脫離EntityManager,狀態(tài)轉(zhuǎn)變?yōu)閐etached entityManager.close(); / 脫離EntityManager后,我們?nèi)匀豢梢孕薷腇ather的屬性 father.setName( "newName" ); / 在稍后的,我們可以將father重新附和到一個(gè)新的或者原來(lái)的

43、EntityManager中 EntityManager newEntityManager = emf.createEntityManager(); / 附合( merge )需要在事務(wù)中進(jìn)行 newEntityManager.getTransaction().begin(); newEntityManager.merge( father ); / commit后father中的被修改的內(nèi)容會(huì)同步到數(shù)據(jù)庫(kù)。 newEntityManager.getTransaction().commit();   5.     JPA QueryJP

44、A的查詢語(yǔ)言(JP)是一種和SQL非常類似的中間性和對(duì)象化查詢語(yǔ)言。它可以被編譯成不同的底層數(shù)據(jù)庫(kù)能接受的SQL,從而屏蔽不同數(shù)據(jù)庫(kù)的差異,確保用JPQL查詢語(yǔ)言編寫的代碼可在不同的數(shù)據(jù)庫(kù)上運(yùn)行。比起EJB 2.1的查詢語(yǔ)言,EJB3可以運(yùn)行期構(gòu)造,支持多態(tài),遠(yuǎn)遠(yuǎn)比EJB 2.1的查詢更靈活和功能強(qiáng)大。在程序中使用JPQL可以使用大寫(SELECT)或者小寫(select),但不要大小寫(比如:Select)混合使用。 5.1 Query接口是EJB3查詢操作的接口。進(jìn)行查詢,首先要通過(guò)EntityManager 獲得Query對(duì)象。 public Query createQuery(Stri

45、ng ejbqlString); 下面我們做一個(gè)最簡(jiǎn)單的查詢,查詢所有的類。 final Query query = entityManager.createQuery( "select o from Order o"); final List result = query.getResultList(); final Iterator iterator = result.iterator(); while( iterator.hasNext() ) /處理Order 注意"from Order"。"Order"在EJB3查詢中稱為類

46、的abstract schema Type。查詢Entity在JPQL中都是針對(duì)Entity的Abstract Schema Type進(jìn)行查詢。 在同一個(gè)EntityManagerFactory中,不允許同時(shí)有兩個(gè)Abstract Schema Type相同的Entity類。比如不允許同時(shí)有和。 Query返回一個(gè)List的集合結(jié)果,我們可以用Iterator或者List.get( int )的方法來(lái)獲得每個(gè)符合條件的Entity。 如果查詢結(jié)果結(jié)合中包含所有符合條件的Entity, EJB3 Persistence運(yùn)行環(huán)境默認(rèn)會(huì)自動(dòng)緩存每次查詢的結(jié)果。這樣下次同樣的查詢操作就無(wú)需訪問(wèn)數(shù)據(jù)庫(kù),

47、而直接從緩存中返回結(jié)果集合。但如果在下次查詢操作之前,有針對(duì)被緩存的Entity類進(jìn)行update/insert/delete操作,則緩存的結(jié)果集合會(huì)自動(dòng)被清空,這樣下次查詢就會(huì)從數(shù)據(jù)庫(kù)獲得數(shù)據(jù), 確保查詢總是獲得正確的結(jié)果,避免緩存臟數(shù)據(jù)。有時(shí)候查詢會(huì)返回海量的數(shù)據(jù)。注意關(guān)閉對(duì)集合結(jié)果的緩存。 / 假設(shè)返回的結(jié)果數(shù)量巨大 final Query query = entityManager.createQuery( "select o from Order o"); / 關(guān)閉對(duì)查詢結(jié)果的緩存 query.setHint( Constants.QUERY_RESULT_CAC

48、HE, "false"); final List result = query.getResultList(); final Iterator iterator = result.iterator(); / 這里我們可以處理海量的數(shù)據(jù) while( iterator.hasNext() ) /處理Order 5.2 簡(jiǎn)單查詢下面是一個(gè)簡(jiǎn)單查詢的例子,可以看到和SQL的使用方法很類似。 final Query query = entityManager.createQuery( "select o from Order o where o.id = 1")

49、;  final Query query = entityManager.createQuery( "select o from Order o where o.id = 1 and o.confirm = 'true' "); final Query query = entityManager.createQuery( "select o from Order o where o.id = 1 or o.customer = 'foo' "); / address是Order類上的一個(gè)對(duì)象變量屬性,Addres

50、s有一個(gè)streetNumber的屬性final Query query = entityManager.createQuery( "select o from Order o where o.address.streetNumber >= 123" ); 注意條件語(yǔ)句中查詢的是Entity的屬性,屬性的名字需要和Entity中的屬性變量名字一致。 5.3 使用參數(shù)查詢參數(shù)查詢也和SQL中的參數(shù)查詢類似。JPQL支持兩種方式的參數(shù)定義方式: 命名參數(shù)和位置參數(shù)。在同一個(gè)查詢中只允許使用一種參數(shù)定義方式。 final Query query = entityM

51、anager.createQuery( "select o from Order o where o.id = :myId"); / 設(shè)置查詢中的參數(shù) query.setParameter( "myId", 2 ); / 可以使用多個(gè)參數(shù) final Query query = entityManager.createQuery( "select o from Order o where o.id = :myId and o.customer = :customerName" ); / 設(shè)置查詢中的參數(shù) query.setParame

52、ter( "myId", 2 ); query.setParameter( "customerName", "foo" ); final Query query = entityManager.createQuery( "select o from Order o where o.id = ?1"); / 設(shè)置查詢中的參數(shù) query.setParameter( 1, 2 );/ 1表示第一個(gè)參數(shù),2是參數(shù)的值 /或者 final Query query = entityManager.createQuery( &

53、quot;select o from Order o where o.id = ?1").setParameter( 1, 2 ); / 可以使用多個(gè)參數(shù) final Query query = entityManager.createQuery( "select o from Order o where o.id = ?1 and o.customer = ?2" ); / 設(shè)置查詢中的參數(shù) query.setParameter( 1, 2 ); query.setParameter( 2, "foo" ); 如果在未來(lái)需要在不同的EJB3

54、運(yùn)行環(huán)境中運(yùn)行,請(qǐng)使用位置參數(shù),保證應(yīng)用是可移植的。 5.4 排序(order by)下面是一個(gè)簡(jiǎn)單查詢的例子,可以看到和SQL的使用方法很類似。"ASC"和"DESC"分別為升序和降序,如果不顯式注明,JPQL中默認(rèn)為asc升序。 / 不注明的話,默認(rèn)為asc為升序, final Query query = entityManager.createQuery( "select o from Order o order by o.id"); final Query query = entityManager.createQuery( "selec

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論