1. 程式人生 > >hibernate延遲載入(load、get區別)

hibernate延遲載入(load、get區別)

由於Spring控制的Hibernate的生命週期只針對資料層和服務層,而未管理到表現層,所以在表現層使用延時載入會出現the owning Session was closed或者no session or session was closed的異常資訊。針對這一點,可以通過hibernate filter的方式來解決。

在WEB.xml檔案中配置filter.
<!-- hibernate session filter -->
<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>*.do</url-pattern>
</filter-mapping>

我們的系統架構是struts+spring+hibernate,struts跟spring的整合是在struts-config.xml里加了個plugin[color=red](注:這個plugin似乎對編碼也有影響,需要用spring的過濾器、自己寫的過濾器達不到效果,以後測試完了,分析下)[/color]
<plug-in
className="org.springframework.WEB.struts.ContextLoaderPlugIn">
<set-property property="contextConfigLocation"
value="/WEB-INF/classes/applicationContext.xml" />

</plug-in>


在WEB.xml中配置hibernateFilter 後,還需要在struts-config.xml裡把plugin去掉,在WEB.xml里加上如下程式碼:
<!--Spring ApplicationContext-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/classes/applicationContext.xml</param-value>
</context-param>

<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>


這樣配置之後如果沒有配置事務,是有問題的。不能進行update和insert操作了。
怎麼辦呢?只需要在filter中加入一個引數
<init-param>
<param-name>singleSession</param-name>
<param-value>true</param-value>
</init-param>
就可以了,當然這樣 每次訪問dao都會新開個session,對效能的影響還是比較大的。最好的辦法當然是[color=red]配置事務[/color]了。

配置說完了,下面介紹下延遲載入的優缺點,即getHibernateTemplate.load() 和get()之間的區別
主要的地方:
getHibernateTemplate.load() 存在延遲載入問題。
getHibernateTemplate.get() 不存在此問題,不採用lazy機制的。
1 當記錄不存在時候,get方法返回null,load方法產生異常,即get()可以取空的資料集,但load()不行。
2 load方法可以返回實體的代理類,get方法則返回真是的實體類
3 load方法可以充分利用hibernate的內部快取和二級快取中的現有資料,而get方法僅僅在內部快取中
進行資料查詢,如果沒有發現數據則將越過二級快取,直接呼叫SQL查詢資料庫。
4 也許別人把資料庫中的資料修改了,load如何在快取中找到了資料,則不會再訪問資料庫,而get則
會返回最新資料。