国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

hibernate持久化對(duì)象狀態(tài)

2019-11-09 16:44:54
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

瞬時(shí)對(duì)象(Transient Objects):使用new操作符初始化的對(duì)象不是立刻就持久化的。他們的狀態(tài)是瞬時(shí)的,也就是說(shuō)他們沒(méi)有任何跟數(shù)據(jù)庫(kù)表相關(guān)聯(lián)的行為,只要應(yīng)用不再引用這些對(duì)象(不再被任何其他對(duì)象所引用),他們的狀態(tài)將會(huì)丟失,并由垃圾回收機(jī)制回收。

臨時(shí)對(duì)象的特征。臨時(shí)對(duì)象具有以下特征:(1) 不處于session的緩存中,也可以說(shuō),不被任何一個(gè)Session實(shí)例關(guān)聯(lián)。(2) 在數(shù)據(jù)庫(kù)中沒(méi)有對(duì)應(yīng)的記錄。在以下情況下,java對(duì)象進(jìn)入臨時(shí)狀態(tài):(1) 當(dāng)通過(guò)new語(yǔ)句剛創(chuàng)建了一個(gè)Java對(duì)象,它處于臨時(shí)狀態(tài),此時(shí)不和數(shù)據(jù)庫(kù)中的任何記錄對(duì)應(yīng)。(2) Session的delete()方法能使一個(gè)持久化對(duì)象或游離對(duì)象轉(zhuǎn)變?yōu)榕R時(shí)對(duì)象。對(duì)于游離對(duì)象,delete()方法從數(shù)據(jù)庫(kù)中刪除與它對(duì)應(yīng)的記錄;對(duì)于持久化對(duì)象,delete()方法從數(shù)據(jù)庫(kù)中刪除與它對(duì)應(yīng)的記錄,并且把它從Session的緩存中刪除。

持久化對(duì)象(Persist Objects):持久實(shí)例是任何具有數(shù)據(jù)庫(kù)標(biāo)識(shí)的實(shí)例。它有持久化管理器Session統(tǒng)一管理,持久實(shí)例是在事務(wù)中進(jìn)行操作的———他們的狀態(tài)在事務(wù)結(jié)束時(shí)同數(shù)據(jù)庫(kù)進(jìn)行同步。當(dāng)事務(wù)提交時(shí),通過(guò)執(zhí)行SQL的INSERT,UPDATE和DELETE語(yǔ)句把內(nèi)存中的狀態(tài)同步到數(shù)據(jù)庫(kù)中。

持久化對(duì)象的特征。持久化對(duì)象具有以下特征:(1) 位于一個(gè)Session實(shí)例的緩存中,也可以說(shuō),持久化對(duì)象總是被一個(gè)Session實(shí)例關(guān)聯(lián)。(2) 持久化對(duì)象和數(shù)據(jù)庫(kù)中的相關(guān)記錄對(duì)應(yīng)。(3) Session在清理緩存時(shí),會(huì)根據(jù)持久化對(duì)象的屬性變化,來(lái)同步更新數(shù)據(jù)庫(kù)。Session的許多方法都能夠觸發(fā)Java對(duì)象進(jìn)入持久化狀態(tài):(1) Session的save()方法把臨時(shí)對(duì)象轉(zhuǎn)變?yōu)槌志没瘜?duì)象。(2) Session的load()或get()方法返回的對(duì)象總是處于持久化狀態(tài)。(3) Session的find()方法返回的List集合中存放的都是持久化對(duì)象。(4) Session的update()、saveOrUpdate()和lock()方法使游離對(duì)象轉(zhuǎn)變?yōu)槌志没瘜?duì)象。(5)當(dāng)一個(gè)持久化對(duì)象關(guān)聯(lián)一個(gè)臨時(shí)對(duì)象,在允許級(jí)聯(lián)保存的情況下,Session在清理緩存時(shí)會(huì)把這個(gè)臨時(shí)對(duì)象也轉(zhuǎn)變?yōu)槌志没瘜?duì)象。hibernate保證在同一個(gè)Session實(shí)例的緩存中,數(shù)據(jù)庫(kù)表中的每條記錄只對(duì)應(yīng)惟一的持久化對(duì)象。例如對(duì)于以下代碼,共創(chuàng)建了兩個(gè)Session實(shí)例:session1和session2。session1和session2擁有各自的緩存。在session1的緩存中,只會(huì)有惟一的OID為1的Customer持久化對(duì)象,在session2的緩存中,也只會(huì)有惟一的OID為2的Customer持久化對(duì)象。因此在內(nèi)存中共有兩個(gè)Customer持久化對(duì)象,一個(gè)屬于session1的緩存,一個(gè)屬于session2的緩存。引用變量a和b都引用session1緩存中的Customer持久化對(duì)象,而引用變量c引用session2緩存中的Customer持久化對(duì)象:Session session1=sessionFactory.openSession();Session session2=sessionFactory.openSession();Transaction tx1 = session1.beginTransaction();Transaction tx2 = session2.beginTransaction();

Customer a=(Customer)session1.load(Customer.class,new Long(1));Customer b=(Customer)session1.load(Customer.class,new Long(1));Customer c=(Customer)session2.load(Customer.class,new Long(1));

System.out.PRintln(a= =b); //trueSystem.out.println(a= =c); //false

tx1.commit();tx2.commit();session1.close();session2.close();Java對(duì)象的持久化狀態(tài)是相對(duì)于某個(gè)具體的Session實(shí)例的,以下代碼試圖使一個(gè)Java對(duì)象同時(shí)被兩個(gè)Session實(shí)例關(guān)聯(lián):Session session1=sessionFactory.openSession();Session session2=sessionFactory.openSession();Transaction tx1 = session1.beginTransaction();Transaction tx2 = session2.beginTransaction();

Customer c=(Customer)session1.load(Customer.class,new Long(1)); //Customer對(duì)象被session1關(guān)聯(lián)session2.update(c); //Customer對(duì)象被session2關(guān)聯(lián)c.setName("Jack"); //修改Customer對(duì)象的屬性

tx1.commit(); //執(zhí)行update語(yǔ)句tx2.commit(); //執(zhí)行update語(yǔ)句session1.close();session2.close();

當(dāng)執(zhí)行session1的load()方法時(shí),OID為1的Customer對(duì)象被加入到session1的緩存中,因此它是session1的持久化對(duì)象,此時(shí)它還沒(méi)有被session2關(guān)聯(lián),因此相對(duì)于session2,它處于游離狀態(tài)。當(dāng)執(zhí)行session2的update()方法時(shí),Customer對(duì)象被加入到session2的緩存中,因此也成為session2的持久化對(duì)象。接下來(lái)修改Customer對(duì)象的name屬性,會(huì)導(dǎo)致兩個(gè)Session實(shí)例在清理各自的緩存時(shí),都執(zhí)行相同的update語(yǔ)句:update CUSTOMERS set NAME='Jack' …… where ID=1;在實(shí)際應(yīng)用程序中,應(yīng)該避免一個(gè)Java對(duì)象同時(shí)被多個(gè)Session實(shí)例關(guān)聯(lián),因?yàn)檫@會(huì)導(dǎo)致重復(fù)執(zhí)行SQL語(yǔ)句,并且極容易出現(xiàn)一些并發(fā)問(wèn)題。

離線對(duì)象(Detached Objects):Session關(guān)閉之后,持久化對(duì)象就變?yōu)殡x線對(duì)象。離線表示這個(gè)對(duì)象不能再與數(shù)據(jù)庫(kù)保持同步,他們不再受Hibernate管理。

游離對(duì)象的特征。游離對(duì)象具有以下特征:(1) 不再位于Session的緩存中,也可以說(shuō),游離對(duì)象不被Session關(guān)聯(lián)。(2) 游離對(duì)象是由持久化對(duì)象轉(zhuǎn)變過(guò)來(lái)的,因此在數(shù)據(jù)庫(kù)中可能還存在與它對(duì)應(yīng)的記錄(前提條件是沒(méi)有其他程序刪除了這條記錄)。游離對(duì)象與臨時(shí)對(duì)象的相同之處在于,兩者都不被Session關(guān)聯(lián),因此Hibernate不會(huì)保證它們的屬性變化與數(shù)據(jù)庫(kù)保持同步。游離對(duì)象與臨時(shí)對(duì)象的區(qū)別在于:前者是由持久化對(duì)象轉(zhuǎn)變過(guò)來(lái)的,因此可能在數(shù)據(jù)庫(kù)中還存在對(duì)應(yīng)的記錄,而后者在數(shù)據(jù)庫(kù)中沒(méi)有對(duì)應(yīng)的記錄。Session的以下方法使持久化對(duì)象轉(zhuǎn)變?yōu)橛坞x對(duì)象:(1) 當(dāng)調(diào)用Session的close()方法時(shí),Session的緩存被清空,緩存中的所有持久化對(duì)象都變?yōu)橛坞x對(duì)象。如果在應(yīng)用程序中沒(méi)有引用變量引用這些游離對(duì)象,它們就會(huì)結(jié)束生命周期。(2)Session的evict()方法能夠從緩存中刪除一個(gè)持久化對(duì)象,使它變?yōu)橛坞x狀態(tài)。當(dāng)Session的緩存中保存了大量的持久化對(duì)象,會(huì)消耗許多內(nèi)存空間,為了提高性能,可以考慮調(diào)用evict()方法,從緩存中刪除一些持久化對(duì)象。但是多數(shù)情況下不推薦使用evict()方法,而應(yīng)該通過(guò)查詢語(yǔ)言,或者顯式的導(dǎo)航來(lái)控制對(duì)象圖的深度。

 

 

Java對(duì)象在JVM中的生命周期:

創(chuàng)建一個(gè)Java對(duì)象時(shí),JVM會(huì)為這個(gè)對(duì)象分配一個(gè)內(nèi)存空間,只要這個(gè)對(duì)象被引用變量引用,就一直存在于內(nèi)存中,如果一個(gè)對(duì)象不被任何引用變量引用,就結(jié)束生命周期。Java集合(List、Map、Set)存放的是Java對(duì)象的引用,當(dāng)向集合中添加一個(gè)對(duì)象時(shí),其實(shí)是把這個(gè)對(duì)象的引用添加到集合中。因此集合中含有的對(duì)象生命周期一直存在。

 理解Session的緩存:

在Session接口的實(shí)現(xiàn)中定義一系列的Java集合,這些集合構(gòu)成了Session的緩存。

Session緩存的作用:1、減少訪問(wèn)數(shù)據(jù)庫(kù)的頻率,可以提高數(shù)據(jù)庫(kù)訪問(wèn)的性能。2、保證緩存中的對(duì)象與數(shù)據(jù)庫(kù)中的相關(guān)記錄保持同步。3、當(dāng)緩存中的持久化對(duì)象(位于緩存中的對(duì)象)之間存在循環(huán)關(guān)聯(lián)關(guān)系時(shí),Sessioin會(huì)保證不出現(xiàn)訪問(wèn)對(duì)象的死循環(huán)。

在Hibernate應(yīng)用中Java對(duì)象的狀態(tài):

臨時(shí)狀態(tài)(transient):剛用new語(yǔ)句創(chuàng)建,還沒(méi)有被持久化,不處于Session的緩存中。處于臨時(shí)狀態(tài)的Java對(duì)象稱為臨時(shí)對(duì)象。

持久化狀態(tài)(persistent):已經(jīng)被持久化,加入到Session的緩存中。處于持久化狀態(tài)的Java對(duì)象稱為持久化對(duì)象。

游離狀態(tài)(detached):已經(jīng)被持久化,但不再處于Session的緩存中。處于游離狀態(tài)的Java對(duì)象稱為游離對(duì)象。

Java對(duì)象:開(kāi)始生命周期——》臨時(shí)狀態(tài)——》持久化狀態(tài)——》游離狀態(tài)——》結(jié)束生命周期

 

 Session的保存、更新、刪除、查詢方法:

1、Session的save()方法

session.save(customer);完成的操作:

(1)把Customer對(duì)象加載到緩存中,使它變?yōu)槌志没瘜?duì)象。

(2)選用映射文件指定的標(biāo)識(shí)符生成器為持久化對(duì)象分配唯一的OID。Customer.hbm.xml文件中<id>元素的<generator>子元素指定標(biāo)識(shí)符生成器。

(3)計(jì)劃執(zhí)行一個(gè)insert語(yǔ)句,把Customer對(duì)象當(dāng)前的屬性值組裝到insert語(yǔ)句中。

insert into CUSTOMERS(ID, NAME, ......) values(1, "Tom", ......)

save()方法并不立即執(zhí)行SQL insert語(yǔ)句。只有當(dāng)Session清理緩存時(shí),才會(huì)執(zhí)行SQL語(yǔ)句。

2、Session的update()方法

session.update(customer);完成的操作:

(1)把Customer對(duì)象重新加入到Session緩存中,使它變?yōu)槌志没瘜?duì)象。

(2)計(jì)劃執(zhí)行一個(gè)update語(yǔ)句。Session只有在清理緩存時(shí)才會(huì)執(zhí)行update語(yǔ)句,并且在執(zhí)行時(shí)才會(huì)把Customer對(duì)象當(dāng)前的屬性值組裝到update語(yǔ)句中。

(3)只要通過(guò)update()方法使游離對(duì)象被一個(gè)Session關(guān)聯(lián),即使沒(méi)有修改Customer對(duì)象的任何屬性,Session在清理緩存時(shí)也會(huì)執(zhí)行由update()方法計(jì)劃的update語(yǔ)句。

update CUSTOMERS set NAME="Tom", ...... where ID=1

如果希望Session僅當(dāng)修改了Customer對(duì)象的屬性時(shí),才執(zhí)行update語(yǔ)句,可把映射文件Customer.hbm.xml中<class>元素的"select-before-update"設(shè)為true(該屬性默認(rèn)為false)

<class name="mypack.Customer" table="CUSTOMERS" select-before-update="true">

當(dāng)Session清理緩存時(shí),先執(zhí)行一條select語(yǔ)句,然后比較Customer對(duì)象的屬性是否和從數(shù)據(jù)庫(kù)中檢索出來(lái)的記錄一致,只有在不一致時(shí)才執(zhí)行update語(yǔ)句。

3、Session的saveOrUpdate()方法

如果傳入的參數(shù)是臨時(shí)對(duì)象,就調(diào)用save()方法;如果傳入的參數(shù)是游離對(duì)象,就調(diào)用update()方法;如果傳入的參數(shù)是持久化對(duì)象,那就直接返回。

Hibernate判斷臨時(shí)對(duì)象的條件:

(1)Java對(duì)象的OID取值為null

(2)Java對(duì)象具有version屬性并且取值為null

(3)在映射文件中為<id>元素設(shè)置了unsaved-value屬性,并且OID取值與unsaved-value屬性只匹配

(4)在映射文件中為version屬性設(shè)置了unsaved-value屬性,并且version屬性取值與unsaved-value屬性值匹配

(5)自定義了Hibernate的Interceptor實(shí)現(xiàn)類,并且Interceptor的isUnsaved()方法返回Boolean.TRUE

4、Session的load()方法和get()方法

根據(jù)給定的OID從數(shù)據(jù)庫(kù)中加載一個(gè)持久化對(duì)象。

當(dāng)數(shù)據(jù)庫(kù)中不存在與OID對(duì)應(yīng)的記錄時(shí)

load()方法,返回ObjectNotFoundException異常

get()方法,返回null。

5、Session的delete()方法

如果傳入的參數(shù)是持久化對(duì)象,Session就計(jì)劃執(zhí)行一個(gè)delete語(yǔ)句;如果傳入的參數(shù)是游離對(duì)象,先使游離對(duì)象被Session關(guān)聯(lián),使它變?yōu)槌志没瘜?duì)象,然后計(jì)劃執(zhí)行一個(gè)delete語(yǔ)句。

Session只有在清理緩存的時(shí)候才會(huì)執(zhí)行delete語(yǔ)句。只有當(dāng)調(diào)用Session的close()方法時(shí),才會(huì)從Session的緩存中刪除該對(duì)象。

session.delete(customer);

session.delete("from Customer as c where c.id>8");

級(jí)聯(lián)操縱對(duì)象圖

在對(duì)象-關(guān)系關(guān)聯(lián)映射文件中,用于映射持久化類之間關(guān)聯(lián)關(guān)系的元素<set>、<many-to-one>、<one-to-one>有cascade屬性,用于指定如何操縱與當(dāng)前對(duì)象關(guān)聯(lián)的其他對(duì)象。

cascade屬性可選值:none、save-update、delete、all、delete-orphan、all-delete-orphan

Hibernate與觸發(fā)器協(xié)同工作

能激發(fā)觸發(fā)器運(yùn)行的事件:

插入(insert)記錄事件、更新(update)記錄事件、刪除(delete)記錄事件

 利用攔截器(Interceptor)生成審計(jì)日志

用戶定義的攔截器必須實(shí)現(xiàn)org.hibernate.Interceptor接口。

Interceptor對(duì)象有兩種存放方式:

SessionFactory.openSession(Interceptor):為每個(gè)Session實(shí)例分配一個(gè)Interceptor實(shí)例,這個(gè)實(shí)例存放在Session范圍內(nèi)。

Configuration.setInterceptor(Interceptor):為SessionFactory實(shí)例分配一個(gè)Interceptor實(shí)例,這個(gè)實(shí)例存放在SessionFactory范圍內(nèi),被所有Session實(shí)例共享。

 

 

 

操縱持久化對(duì)象

 

1.   理解Session的緩存:在Java里面,緩存通常是指Java對(duì)象的屬性占用的內(nèi)存空間,通常是一些集合類型的屬性。在session接口的實(shí)現(xiàn)類SessionImpl中定義了一系列的Java集合,這些Java集合就構(gòu)成了Session的緩存。當(dāng)Session的save()方法持久化一個(gè)對(duì)象時(shí),這個(gè)對(duì)象被加入到Session的緩存中,以后即使應(yīng)用程序中的引用變量不再引用這個(gè)對(duì)象,只要Session的緩存還沒(méi)有被清空,這個(gè)對(duì)象仍然處于生命周期中。當(dāng)Session的load()方法加載一個(gè)對(duì)象時(shí),Session會(huì)先判斷緩存中是否已經(jīng)存在這個(gè)對(duì)象了,如果存在,就不需要再到數(shù)據(jù)庫(kù)中重新加載了。Session的緩存有兩大作用:1.1.       減少訪問(wèn)數(shù)據(jù)庫(kù)的頻率。1.2.       保證緩存中的對(duì)象與數(shù)據(jù)庫(kù)中的相關(guān)記錄保持同步。Session有兩個(gè)方法:一個(gè)commit()事務(wù)提交方法,還有flush()刷新緩存方法,都有著清理緩存的作用。flush()進(jìn)行緩存的清理,執(zhí)行一系列的SQL語(yǔ)句,但不會(huì)提交事務(wù)。而commit()方法會(huì)先調(diào)用flush()方法,然后在提交事務(wù)。2.   定義持久化類的建議:在應(yīng)用程序中,用來(lái)實(shí)現(xiàn)業(yè)務(wù)問(wèn)題實(shí)體的(如,在電子商務(wù)應(yīng)用程序中的Customer和Order) 類就是持久化類。如果這些持久化類遵循一些簡(jiǎn)單的規(guī)則,Hibernate能夠工作得更好,這些規(guī)則也被稱作簡(jiǎn)單傳統(tǒng)Java對(duì)象(POJO:Plain Old Java Object)編程模型。但是這些規(guī)則并不是必需的。最好要遵循以下幾條主要的規(guī)則:1)     實(shí)現(xiàn)一個(gè)默認(rèn)的(即無(wú)參數(shù)的)構(gòu)造方法(constructor):我們強(qiáng)烈建議,在Hibernate中,為了運(yùn)行期代理的生成,構(gòu)造方法至少是包(package)內(nèi)可見(jiàn)的。2)     提供一個(gè)標(biāo)識(shí)屬性(identifier property):我們建議你對(duì)持久化類聲明命名一致的標(biāo)識(shí)屬性。我們還建議你使用一個(gè)可以為空(也就是說(shuō),不是原始類型)的類型。3)     使用非final的類:代理(proxies)是Hibernate的一個(gè)重要的功能,它依賴的條件是,持久 化類或者是非final的,或者是實(shí)現(xiàn)了一個(gè)所有方法都聲明為public的接口。你也應(yīng)該避免在非final類中聲明public final的方法。4)     為持久化字段聲明訪問(wèn)器(accessors):5)     如果你有如下需求,你必須重載 equals() 和 hashCode()方法:l 想把持久類的實(shí)例放入Set中(當(dāng)表示多值關(guān)聯(lián)時(shí),推薦這么做)l 想重用脫管實(shí)例Hibernate保證,僅在特定會(huì)話范圍內(nèi),持久化標(biāo)識(shí)(數(shù)據(jù)庫(kù)的行)和Java標(biāo)識(shí)是等價(jià)的。因此,一旦 我們混合了從不同會(huì)話中獲取的實(shí)例,如果希望Set有明確的語(yǔ)義,就必須實(shí)現(xiàn)equals() 和hashCode()。3.   持久化對(duì)象的三種狀態(tài):一個(gè)持久化類的實(shí)例可能處于三種不同狀態(tài)中的某一種。3.1.   瞬時(shí)(transient)狀態(tài):該實(shí)例是剛用new語(yǔ)句創(chuàng)建的,還沒(méi)有被持久化,不處于任何Session的緩存中。它沒(méi)有持久化標(biāo)識(shí)(相當(dāng)于主鍵值)。處于瞬時(shí)狀態(tài)的實(shí)例被稱為瞬時(shí)對(duì)象。它的特點(diǎn)是:不和任何一個(gè)Session實(shí)例關(guān)聯(lián)。在數(shù)據(jù)庫(kù)中沒(méi)有對(duì)應(yīng)的記錄。3.2.   持久化(persistent)狀態(tài):已經(jīng)被持久化,加入到Session緩存中。處于持久化狀態(tài)的實(shí)例被稱為持久化對(duì)象。實(shí)例目前與某個(gè)Session有關(guān)聯(lián)。 它擁有持久化標(biāo)識(shí)(相當(dāng)于主鍵值),并且可能在數(shù)據(jù)庫(kù)中有一個(gè)對(duì)應(yīng)的行。 Hibernate保證在同一個(gè)Sesion實(shí)例的緩存中,數(shù)據(jù)庫(kù)中的每條記錄只對(duì)應(yīng)唯一的持久化對(duì)象。 它的特點(diǎn)是:       持久化對(duì)象總是被一個(gè)Session實(shí)例關(guān)聯(lián)。持久化對(duì)象和數(shù)據(jù)庫(kù)中的相關(guān)記錄對(duì)應(yīng)。Session在清理緩存時(shí),會(huì)根據(jù)持久化對(duì)象的屬性變化,來(lái)同步更新數(shù)據(jù)庫(kù)。3.3.   脫管(detached)狀態(tài):已經(jīng)被持久化過(guò),但不再處于Session的緩存中。處于脫管狀態(tài)的實(shí)例被稱為脫管對(duì)象。實(shí)例曾經(jīng)與某個(gè)持久化上下文發(fā)生過(guò)關(guān)聯(lián),不過(guò)那個(gè)上下文被關(guān)閉了, 或者這個(gè)實(shí)例是被序列化(serialize)到另外的進(jìn)程。 它擁有持久化標(biāo)識(shí),并且在數(shù)據(jù)庫(kù)中可能存在一個(gè)對(duì)應(yīng)的行。 對(duì)于脫管狀態(tài)的實(shí)例,Hibernate不保證任何持久化標(biāo)識(shí)和Java標(biāo)識(shí)的關(guān)系。它的特點(diǎn)是:不再位于session的緩存中,即它不再和session關(guān)聯(lián)。它擁有持久化標(biāo)識(shí)。  4.   Session的保存、刪除、更新和查詢方法:4.1.   Session的save()方法:使用一個(gè)臨時(shí)對(duì)象轉(zhuǎn)變?yōu)槌志脤?duì)象。方法簽名:public Serializable save(Object object) throws HibernateException; 它完成以下操作:1)     把持久化類的實(shí)例加入到緩存中,使它變?yōu)槌志没瘜?duì)象。2)     選用映射文件指定的標(biāo)識(shí)符生成器為持久化對(duì)象分配唯一的OID。3)     計(jì)劃執(zhí)行一個(gè)insert語(yǔ)句,把持久化對(duì)象當(dāng)前的屬性值組裝到insert 語(yǔ)句(SQL DML)中。值得注意的是,save()方法并不是立即執(zhí)行SQL insert語(yǔ)句。只有當(dāng)Session清理緩存時(shí),才會(huì)執(zhí)行SQL insert語(yǔ)句。另外,需要注意的是:Hibernate通過(guò)持久化對(duì)象的OID來(lái)維持它和數(shù)據(jù)庫(kù)相關(guān)記錄的對(duì)應(yīng)關(guān)系。所以當(dāng)持久化的實(shí)例處于持久化狀態(tài)時(shí),不允許程序隨意修改它的OID。其實(shí),無(wú)論java對(duì)象處于瞬時(shí)狀態(tài)、持久化狀態(tài)還是脫管狀態(tài),程序都不應(yīng)該修改它的OID。4.2.   Session的update()方法:使一個(gè)脫管對(duì)象轉(zhuǎn)變?yōu)槌志没瘜?duì)象。方法簽名:public void update(Object object) throws HibernateException; 它完成以下操作:1)     把脫管對(duì)象重新加入到Session緩存中,使它變?yōu)槌志没瘜?duì)象。2)     計(jì)劃執(zhí)行一個(gè)update語(yǔ)句。值得注意的是,Session只有在清理緩存的時(shí)候才會(huì)執(zhí)行update語(yǔ)句,并且在執(zhí)行時(shí)才會(huì)把持久化對(duì)象當(dāng)前的屬性值組裝到update語(yǔ)句中。4.3.   Session的saveOrUpdate()方法:       方法簽名:public void saveOrUpdate(Object object) throws HibernateException ; saveOrUpdate()方法同時(shí)包含了save()與update()方法的功能,如果傳入的參數(shù)是瞬時(shí)對(duì)象,就調(diào)用save()方法;如果傳入的參數(shù)是脫管對(duì)象,就調(diào)用update()方法;如果傳入的參數(shù)是持久化對(duì)象,方法就直接返回。那么,saveOrUpdate()方法如果判斷一個(gè)對(duì)象處于瞬時(shí)狀態(tài)不是脫管狀態(tài)呢?如果滿足以下情況之一,Hibernate就把它作為臨時(shí)對(duì)象:1)     Java對(duì)象的OID取值為null。2)     Java對(duì)象具有version屬性,并且取值了null。3)     在映射文件中為<id>元素設(shè)置了unsaved-value屬性,并且OID取值與unsaved-value屬性值匹配。4)     在映射文件中為<version>元素設(shè)置了unsaved-value屬性,并且version屬性取值與unsaved-value屬性值匹配。5)     自定義了Hibernate的Interceptor實(shí)現(xiàn)類,并且Interceptor的isUnsaved()方法返回Boolean.TRUE。4.4.   Session的delete()方法:方法簽名:public void delete(Object object) throws HibernateException; delete()方法用于從數(shù)據(jù)庫(kù)中刪除與Java對(duì)象對(duì)應(yīng)的記錄。如果傳入的參數(shù)是持久化對(duì)象,Session就計(jì)劃執(zhí)行一個(gè)delete語(yǔ)句。如果傳入的參數(shù)是游離對(duì)象,先使游離對(duì)象被Session關(guān)聯(lián),使它變?yōu)槌志没瘜?duì)象,然后計(jì)劃執(zhí)行一個(gè)delete語(yǔ)句。值得注意的也是,Session只有在清理緩存的時(shí)候才會(huì)執(zhí)行delete語(yǔ)句。5.   通過(guò)主鍵ID取得數(shù)據(jù)對(duì)象:5.1.   Session的get()方法:       方法簽名:public Object get(Class clazz, Serializable id) throws HibernateException; 根據(jù)給定的OID從數(shù)據(jù)庫(kù)中加載一個(gè)持久化對(duì)象,若數(shù)據(jù)庫(kù)中不存在與OID對(duì)應(yīng)的記錄,此方法返回null。       get()方法的執(zhí)行順序如下:1)     首先通過(guò)id在session緩存中查找對(duì)象,如果存在此id主鍵值的對(duì)象,直接將其返回。如果不存在,將進(jìn)行第2步。2)     在二級(jí)緩存中查找,找到后將其返回。3)     如果在session緩存和二級(jí)緩存中都找不到此對(duì)象,剛從數(shù)據(jù)庫(kù)加載擁有此id的對(duì)象。如果數(shù)據(jù)庫(kù)也不存在這個(gè)擁有此id的對(duì)象,則返回null。5.2.   Session的load()方法:方法簽名:public Object load(Class theClass, Serializable id) throws HibernateException; 根據(jù)給定的OID從數(shù)據(jù)庫(kù)中加載一個(gè)持久化對(duì)象,若數(shù)據(jù)庫(kù)中不存在與OID對(duì)應(yīng)的記錄,此方法將拋出org.hibernate.ObjectNotFoundException異常。對(duì)于get和load的根本區(qū)別,一句話,hibernate對(duì)于load方法認(rèn)為該數(shù)據(jù)在數(shù)據(jù)庫(kù)中一定存在,可以放心的使用代理來(lái)延遲加載,如果在使用過(guò)程中發(fā)現(xiàn)了問(wèn)題,只能拋異常;而對(duì)于get方法,hibernate一定要獲取到真實(shí)的數(shù)據(jù),否則返回null。6.   Query接口:Hibernate提供Query接口,它用來(lái)執(zhí)行HQL語(yǔ)句。6.1.   綁定參數(shù)6.1.1.      使用 “?”按參數(shù)位置綁定:通過(guò)Query接口執(zhí)行HQL語(yǔ)句時(shí),可以先設(shè)定查詢參數(shù),然后通過(guò)setXXX()方法來(lái)綁定參數(shù)。如下

Query query = session.createQuery("from User as u where u.age > ? and u.name like ?");query.setInteger(0, 25);query.setString(1, "%a%");List list = query.list();

Hibernate提供了綁定各種類型的參數(shù)的方法,如參數(shù)為字符串類型,可調(diào)用setString(),如果參數(shù)為整數(shù)類型,可調(diào)用setInteger()方法,以此類推。這些setXXX()方法的第1個(gè)參數(shù)HQL查詢語(yǔ)句中參數(shù)的位置,第2個(gè)參數(shù)代表HQL查詢語(yǔ)句中參數(shù)的值。6.1.2.      使用 “:” 后跟變量名來(lái)按命名參數(shù)綁定:可以使用命名參數(shù)來(lái)取代使用“?”設(shè)置參數(shù)的方法,這可以不用依照特定的順序來(lái)設(shè)定參數(shù)值,如上例可改成:

Query query = session.createQuery("from User as u where u.age > :minAge and u.name like likeName");query.setInteger("minAge", 25);query.setString("likeName", "%a%");List list = query.list();

使用命名參數(shù)方式的綁定方式有以下優(yōu)勢(shì):1)     代碼可讀性更好。2)     命名參數(shù)不依賴它們?cè)诓樵冏址谐霈F(xiàn)的位置。3)     在同一個(gè)查詢中可以多次使用。所以,應(yīng)該優(yōu)先考慮使用命名參數(shù)方式。6.2.   使用命名查詢(nameQuery):可以將HQL語(yǔ)句編寫(xiě)在程序之外,以避免硬編碼在程序之中,這樣要修改HQL語(yǔ)句時(shí)就很方便。在xxx.hbm.xml中使用<qiuery/>標(biāo)簽,并在<![CDATA[ 與 ]]> 之間編寫(xiě)HQL,如下Student.hbm.xml:

......<hibernate-mapping>   <classname="org.qiujy.demo.User"table="user">       <idname="id"column="id"type="java.lang.Integer">           <generatorclass="native"/>       </id>       <propertyname="name"column="name"type="java.lang.String"/>       <propertyname="age"column="age"type="java.lang.Integer"/>   </class><query name="queryUserByAgeAndName">    <![CDATA[    from User as u where u.age >:minAge and u.name like :likeName]]></query></hibernate-mapping>

在代碼中這樣來(lái)調(diào)用:

Query query = session.getNamedQuery("queryUserByAgeAndName");query.setInteger("minAge", 25);query.setString("likeName", "%a%");List list = query.list();

6.3.   Query接口的list()方法:Query接口的list()方法用于取得一個(gè)List類的實(shí)例,此實(shí)例中包括的可能是一個(gè)對(duì)象集合,也可能是一個(gè)對(duì)象數(shù)組集合。最常見(jiàn)的使用是用list()方法來(lái)取得一組符合實(shí)例對(duì)象。如上示例。6.4.   Query接口的uniqueResult()方法:當(dāng)確信使用的HQL語(yǔ)句查詢時(shí)返回的集合中只有一個(gè)對(duì)象時(shí),就可以使用這個(gè)方法。但如果返回結(jié)果中有多個(gè)對(duì)象,使用這個(gè)方法會(huì)拋出org.hibernate.NonUniqueResultException 異常,說(shuō)“query did not return a unique result”。
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 曲阳县| 万年县| 大连市| 黄梅县| 江川县| 巨野县| 祁连县| 资中县| 淅川县| 枣阳市| 都昌县| 皮山县| 江口县| 莲花县| 名山县| 南安市| 铜梁县| 卫辉市| 项城市| 依兰县| 滕州市| 阳朔县| 巨野县| 长海县| 宁阳县| 镇宁| 屯昌县| 巴彦县| 遂昌县| 泰兴市| 通辽市| 静海县| 湛江市| 封丘县| 昆明市| 鄂伦春自治旗| 深州市| 西安市| 婺源县| 雷波县| 西畴县|