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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Hibernate懒加载问题的5种解决方案

發布時間:2023/12/4 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Hibernate懒加载问题的5种解决方案 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

**

1、Hibernate基礎

**
Hibernate基礎,傳送門

**

2、什么是Hibernate懶加載

**

當我們查詢一個對象的時候,在默認情況下,返回的只是該對象的代理對象,當用戶去使用該對象的屬性時,才會向數據庫再一次發出查詢語句。

例如,有一個對象是Employee,還有一個對象是Department。顯然,對于Employee相對Department來說,是多對一的關系;而對于Department相對Employee來說,是一對多的關系。當我們查詢Employee對象的時候,如果希望通過employee對象的屬性department查詢到所對應的Department,那么是會拋出異常的。這是因為懶加載的存在,在session關閉之后,hibernate又向數據庫發出一次請求,結果就拋出異常了。

**

3、懶加載的4種解決方案

**

3.1 顯式初始化(在查詢方法內部)

要查詢某員工屬于哪個部門的時候,需要對Department進行預先查詢

使用語句

Hibernate.initialize(Department.class);

3.2 修改對象關系文件,將lazy改寫lazy=false,即關閉懶加載

以上兩種方法,確實可以解決問題,但是缺點是無論后面是否使用該對象,hibernate都會向數據庫發出SQL語句請求數據,造成不必要的性能浪費。

3.3 使用過濾器(web項目)

①獲取session的方式必須使用getCurrentSession

②特殊的關閉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);//請求一直在走 tx.commit(); } catch (Exception e) { // TODO: handle exception if(tx != null){ tx.rollback(); } }finally{ //特殊的關閉方式 HibernateUtil.closeCurrentSession(); } }

3.4 在SSH框架中,使用spring提供的openSessionView

其原理和第三種方法中使用Filter類似,只不過這個filter是spring提供的。使用時只需要在web.xml文件配置如下:

<!-- 使用spring解決懶加載問題 --> <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中方法也能解決懶加載的問題,其中第4種方法也是目前使用較多的。但是這兩種方法也是有缺點的,缺點就是延長了session關閉的時間,session的生命周期變長。沒有使用該方法之前,session是在查詢完數據之后,就被關閉了;而現在,session的關閉是在一次web請求的最后才關閉。

3.5 將hibernate的抓取策略改為join

,也就是left join fetch 或inner join fetch語法, 就是在<many-to-one …/>中配置lazy=“false” fetch=“join” 即可。如:

<many-to-one name="worker" lazy="false" fetch="join" class="com.paixie.dpmain.Worker"><column name="positionId"></column></many-to-one>

**

4、hibernate中的懶加載和急加載的區別

**

懶加載: FatchType.LAZY :在加載一個實體的時候,不會馬上從數據庫中加載,即從數據庫中加載到內存。

急加載:FatchType.EAGER :在加載一個實體時,會立即從數據庫中查詢,與其關聯的類也會被同時查詢。

在我們使用@ManyToOne等時,都會被默認為急加載。

在hibernate中,我們無論是使用懶加載還是急加載,get方法都會一次加載所有基本數據類型屬性的值,而load則不同。

在我們開啟了懶加載之后,load方法只會加載id屬性,所有的非id屬性的訪問操作都不會執行。只有id屬性中有實際值(其實就是你調用load方法時傳的那個),

在session沒有關閉的之前,如果訪問除id外的其他屬性才會發sql語句去查詢,我們經常犯的一個錯誤就是在當前session關閉以后訪問由load()加載的對象的非id屬性,

此時Hibernate嘗試通過當前session發sql查詢,但發現session已經關閉,這樣就會發出no session的異常 。

一般我們將將FetchType.lazy 改成 EAGER ,就可以避免這個錯誤。

但是在我們需要查詢一個表時,如果這個表有很多與其關聯的表,如果使用急加載的話,在第一次加載就會很慢,如果是懶加載相對則會快一些。但是在我們又需要查詢與此表相關的數據的時候

急加載就會很快,因為在第一次加載的時候,已經幫我們全部加載好了。而懶加載則會相對慢一些,因為在我門需要查詢的時候,它才會幫我們去查。

所以讓他們算是各有優缺點。

而我們用哪一種方法更好,則需要根據我們的具體情況去使用了

總結

以上是生活随笔為你收集整理的Hibernate懒加载问题的5种解决方案的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。