日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

(10) Hibernate懒加载详解

發(fā)布時(shí)間:2024/1/23 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 (10) Hibernate懒加载详解 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

懶加載為hibernate中比較常用的特性之一,下面我們?cè)敿?xì)來了解下懶加載的原理和注意事項(xiàng)

Load()方法的懶加載原理

在Hibernate中,查詢方法有兩個(gè),分別是get()和load(),這兩種方法的不同就是load()擁有懶加載的特性。Load()方法就是在查詢某一條數(shù)據(jù)的時(shí)候并不會(huì)直接將這條數(shù)據(jù)以指定對(duì)象的形式來返回,而是在你真正需要使用該對(duì)象里面的一些屬性的時(shí)候才會(huì)去數(shù)據(jù)庫(kù)訪問并得到數(shù)據(jù)。他的好處就是可以減少程序本身因?yàn)榕c數(shù)據(jù)庫(kù)頻繁的交互造成的處理速度緩慢。

以一個(gè)Person類做例子,我們寫一個(gè)查詢的方法如下:

public static void query(int id){ Session session=null; try{ session=HibernateUtil.getSession(); Person person=(Person) session.load(Person.class, id); //System.out.println(person.getName()); }catch(HibernateExceptionex){ ex.printStackTrace(); }finally{ if(session!=null){ session.close(); } } }
然后在Hibernate配置文件中添加以下屬性

<property name="hibernate.show_sql">true</property>

這條屬性的作用為將Hibernate運(yùn)行時(shí)產(chǎn)生的每一條SQL語(yǔ)句都打印出來

?

運(yùn)行上述方法后,我們并沒有看到Hibernate打印任何查詢語(yǔ)句,這時(shí)我們可以將注釋的語(yǔ)句重新調(diào)回來,讓他打印查詢到的person的name。這時(shí)我們可以看到Hibernate產(chǎn)生的查詢語(yǔ)句并看到person的name屬性。這就是懶加載了。

? 那么在Hibernate懶加載的時(shí)候,返回的對(duì)象是空的嗎?答案是否定的,我們可以通過打印person.getClass()方法來驗(yàn)證,打印出來的結(jié)果并不是null,而是一個(gè)Person后面加了一堆很奇怪的字符的類。可以肯定的是懶加載的對(duì)象并不是空,而且這個(gè)對(duì)象的類型不是Person類。那么他到底是什么呢?

其實(shí)這個(gè)兌現(xiàn)我們管它叫做代理對(duì)象,而這個(gè)對(duì)象所屬的類是Person類的子類,是Hibernate自動(dòng)實(shí)現(xiàn)的一個(gè)子類。這個(gè)子類的特點(diǎn)是:當(dāng)你訪問person對(duì)象的某一個(gè)屬性的時(shí)候,他會(huì)自動(dòng)查詢數(shù)據(jù)庫(kù)中對(duì)應(yīng)這個(gè)對(duì)象的數(shù)據(jù)并返回,這就是為什么在創(chuàng)建對(duì)象關(guān)系映射的時(shí)候要求實(shí)體類不能夠?yàn)閒inal類型的原因了。

? 但是這個(gè)對(duì)象是有一個(gè)生命周期的,我們可以改寫上述方法如下:

public static Person query(int id){ Session session=null; Person person=null; try{ session=HibernateUtil.getSession(); person=(Person)session.load(Person.class, id); //System.out.println(person.getName()); }catch(HibernateExceptionex){ ex.printStackTrace(); }finally{ if(session!=null){ session.close(); } } return person; }

調(diào)用這個(gè)方法并返回查詢到的代理對(duì)象,我們可以在返回該對(duì)象后打印該對(duì)象的name屬性,這時(shí)會(huì)拋出一個(gè)org.hibernate.LazyInitializationException異常

? 這就是懶加載不能初始化異常,這就說明了一件事,懶加載的時(shí)候如果想通過代理對(duì)象查詢數(shù)據(jù)庫(kù),需要在該session關(guān)閉以前才可以。但如果一定要在session關(guān)閉以后再使用代理對(duì)象的話,Hibernate中定義了一個(gè)初始化代理對(duì)象的方法initialize(),通過該方法即可將代理對(duì)象初始化。

?

注:在使用代理對(duì)象的getId()方法和getClass()方法的時(shí)候,并不會(huì)拋出不能初始化異常,因?yàn)檫@兩個(gè)屬性并不用查詢數(shù)據(jù)庫(kù)。

?

? 懶加載可以用于關(guān)系映射和集合屬性的操作,而且懶加載是可以關(guān)閉并打開的,下面我們會(huì)根據(jù)不同的情況分析一下懶加載。

?

一對(duì)一的懶加載分析

一對(duì)一的懶加載并不常用,因?yàn)閼屑虞d的目的是為了減少與數(shù)據(jù)庫(kù)的交互,從而提高執(zhí)行效率,而在一對(duì)一關(guān)系中,主表中的每一條數(shù)據(jù)只對(duì)應(yīng)從表的一條數(shù)據(jù)庫(kù),就算都查詢也不會(huì)增加多少交互的成本,而且主表不能有contrained=true,所以主表是不能懶加載的。(從表可以有)

?

注:當(dāng)fetch設(shè)置為join時(shí),懶加載就會(huì)失效。因?yàn)閒etch的作用是抓取方式,他有兩個(gè)值分別問select和join,默認(rèn)值為select。即在設(shè)為join時(shí),他會(huì)直接將從表信息以join方式查詢到而不是再次使用select查詢,這樣導(dǎo)致了懶加載的失效。

?

一對(duì)多和多對(duì)多的懶加載分析

? 與一對(duì)一關(guān)聯(lián)不同,一對(duì)多和一對(duì)多的關(guān)聯(lián)下,主表的每一條屬性都會(huì)對(duì)應(yīng)從表的多條數(shù)據(jù),這個(gè)時(shí)候懶加載就顯得非常有效了。比如一個(gè)部門里面有多個(gè)員工,如果沒有懶加載,每查詢這個(gè)部門的時(shí)候都會(huì)查詢出多個(gè)員工,這會(huì)大大增加與數(shù)據(jù)庫(kù)交互的成本。所以Hbernate默認(rèn)的是加入懶加載的。這就是查詢集合屬性的時(shí)候返回的是一個(gè)PersistentIndexed*類型對(duì)象的原因。該對(duì)象其實(shí)就是一個(gè)代理對(duì)象。當(dāng)然,可以在映射文件中通過將lazy屬性設(shè)為假來禁用。

?

多對(duì)一的懶加載分析

? 雖然多對(duì)一與一對(duì)一關(guān)系方式相同,但是在Hibernate中多對(duì)一時(shí),默認(rèn)是進(jìn)行懶加載的。另外有一點(diǎn)需要注意的是懶加載并不會(huì)區(qū)分集合屬性里面是否有值,即使是沒有值,他依然會(huì)使用懶加載,這也是懶加載不夠完善的地方之一。

?

懶加載的一些細(xì)節(jié)擴(kuò)充

? 有的時(shí)候,我們?cè)趕ession關(guān)閉后仍需要使用懶加載的代理對(duì)象來查詢數(shù)據(jù)庫(kù),這時(shí)我們就需要將代理對(duì)象初始化,不過問題是,當(dāng)我們不能確定初始化后就一定使用該對(duì)象的時(shí)候怎么辦,這樣不是又白白浪費(fèi)了資源嗎?我們可以在使用代理對(duì)象的方法里面加入一個(gè)布爾值參數(shù),這樣當(dāng)我們不需要初始化代理對(duì)象的時(shí)候只要將布爾參數(shù)設(shè)為假。但也是有缺點(diǎn)的,因?yàn)樵谡{(diào)用的時(shí)候,尤其是在別人使用的時(shí)候,參數(shù)越多,方法學(xué)習(xí)成本就會(huì)增加,所以請(qǐng)酌情處理。

? 懶加載也可以用于某些簡(jiǎn)單屬性,但是因?yàn)閷?shí)現(xiàn)起來比較復(fù)雜,而且效果并不明顯,所以并不推薦。



總結(jié)

以上是生活随笔為你收集整理的(10) Hibernate懒加载详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。