淺談解決Hibernate懶加載的4種方式
本文總結(jié)了我在學(xué)習(xí)hibernate的過(guò)程中,解決hibernate懶加載問(wèn)題的四種方式。
所謂懶加載(lazy)就是延時(shí)加載,延遲加載。
什么時(shí)候用懶加載呢,我只能回答要用懶加載的時(shí)候就用懶加載。
至于為什么要用懶加載呢,就是當(dāng)我們要訪問(wèn)的數(shù)據(jù)量過(guò)大時(shí),明顯用緩存不太合適,因?yàn)閮?nèi)存容量有限,為了減少并發(fā)量,減少系統(tǒng)資源的消耗,我們讓數(shù)據(jù)在需要的時(shí)候才進(jìn)行加載,這時(shí)我們就用到了懶加載。
例如,有一個(gè)對(duì)象是Employee,還有一個(gè)對(duì)象是Department。顯然,對(duì)于Employee相對(duì)Department來(lái)說(shuō),是多對(duì)一的關(guān)系;而對(duì)于Department相對(duì)Employee來(lái)說(shuō),是一對(duì)多的關(guān)系。當(dāng)我們查詢(xún)Employee對(duì)象的時(shí)候,如果希望通過(guò)employee對(duì)象的屬性department查詢(xún)到所對(duì)應(yīng)的Department,那么是會(huì)拋出異常的。這是因?yàn)閼屑虞d的存在,在session關(guān)閉之后,hibernate又向數(shù)據(jù)庫(kù)發(fā)出一次請(qǐng)求,結(jié)果就拋出異常了。
下面總結(jié)的是解決這個(gè)問(wèn)題的四種方式:
1.顯式初始化(在查詢(xún)方法內(nèi)部)
要查詢(xún)某員工屬于哪個(gè)部門(mén)的時(shí)候,需要對(duì)Department進(jìn)行預(yù)先查詢(xún)
使用語(yǔ)句
Hibernate.initialize(Department.class);
2.修改對(duì)象關(guān)系文件,將lazy改寫(xiě)lazy=false,即關(guān)閉懶加載
以上兩種方法,確實(shí)可以解決問(wèn)題,但是缺點(diǎn)是無(wú)論后面是否使用該對(duì)象,hibernate都會(huì)向數(shù)據(jù)庫(kù)發(fā)出SQL語(yǔ)句請(qǐng)求數(shù)據(jù),造成不必要的性能浪費(fèi)。
3.使用過(guò)濾器(web項(xiàng)目)
①獲取session的方式必須使用getCurrentSession
②特殊的關(guān)閉session方式
public void doFilter(ServletRequest request, ServletResponse response, FilterChain arg2) throws IOException, ServletException { // TODO Auto-generated method stub Session session = null; Transaction tx = null; try { session = HibernateUtil.getCurrentSession(); tx = session.beginTransaction(); arg2.doFilter(request, response);//請(qǐng)求一直在走 tx.commit(); } catch (Exception e) { // TODO: handle exception if(tx != null){ tx.rollback(); } }finally{ //特殊的關(guān)閉方式 HibernateUtil.closeCurrentSession(); } }
4.在SSH框架中,使用spring提供的openSessionView
其原理和第三種方法中使用Filter類(lèi)似,只不過(guò)這個(gè)filter是spring提供的。使用時(shí)只需要在web.xml文件配置如下:
<!-- 使用spring解決懶加載問(wèn)題 --> <filter> <filter-name>OpenSessionInViewFilter</filter-name> <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class> </filter> <filter-mapping> <filter-name>OpenSessionInViewFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
第3和第4中方法也能解決懶加載的問(wèn)題,其中第4種方法也是目前使用較多的。但是這兩種方法也是有缺點(diǎn)的,缺點(diǎn)就是延長(zhǎng)了session關(guān)閉的時(shí)間,session的生命周期變長(zhǎng)。沒(méi)有使用該方法之前,session是在查詢(xún)完數(shù)據(jù)之后,就被關(guān)閉了;而現(xiàn)在,session的關(guān)閉是在一次web請(qǐng)求的最后才關(guān)閉。
總結(jié)
以上就是本文關(guān)于淺談解決Hibernate懶加載的4種方式的全部?jī)?nèi)容,希望對(duì)大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站其他相關(guān)專(zhuān)題,如有不足之處,歡迎留言指出。感謝朋友們對(duì)本站的支持!
相關(guān)文章
Mybatis Plus 實(shí)現(xiàn)批量插入的示例代碼
本文主要介紹了Mybatis Plus 實(shí)現(xiàn)批量插入的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09攜程Apollo(阿波羅)安裝部署以及java整合實(shí)現(xiàn)
這篇文章主要介紹了攜程Apollo(阿波羅)安裝部署以及java整合實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08關(guān)于springboot使用rocketmq?RocketMQMessageListener參數(shù)問(wèn)題
這篇文章主要介紹了springboot使用rocketmq?RocketMQMessageListener參數(shù)問(wèn)題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值需要的朋友可以參考下2022-11-11基于selenium-java封裝chrome、firefox、phantomjs實(shí)現(xiàn)爬蟲(chóng)
這篇文章主要介紹了基于selenium-java封裝chrome、firefox、phantomjs實(shí)現(xiàn)爬蟲(chóng),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2020-10-10歸并排序時(shí)間復(fù)雜度過(guò)程推導(dǎo)詳解
這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)排序算法之歸并排序,對(duì)歸并排序的原理及實(shí)現(xiàn)過(guò)程做了非常詳細(xì)的解讀,需要的朋友可以參考下,希望能幫助到你2021-08-08Springboot如何使用mybatis實(shí)現(xiàn)攔截SQL分頁(yè)
這篇文章主要介紹了Springboot使用mybatis實(shí)現(xiàn)攔截SQL分頁(yè),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-06-06mybatis?查詢(xún)返回Map<String,Object>類(lèi)型
本文主要介紹了mybatis?查詢(xún)返回Map<String,Object>類(lèi)型,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-03-03