轉載地址:http://hi.baidu.com/accpandsvse/item/2f23543e4c027e302e20c4a5
1、說說爲什麼使用lazy
當使用Hibernate中的one-to-many、many-to one、many-to-many關係映射的時候,一個對象中會包含一個或多個Set來關聯其他的對象。例如:user-groups,當程序取user 對象時,如果一個用戶有多個自定義組,那麼程序將把組的信息也讀取出來,在log中可以看到兩個sql的輸出。但是在頁面的顯示上,也許並不需要顯示這個用戶相關組的信息,這樣系統的消耗就白白浪費了,於是hibernate提供了lazy(延遲加載)的方法來避免這一情況的發生,我們只需要在 user.hbm.xml中設置lazy=true,就能實現延遲加載。
<set name="groupses" table="usergroups" catalog="many" cascade="save-update" lazy="true">
<key>
<column name="userid" length="32" not-null="true" />
</key>
<many-to-many entity-name="com.example.model.Groups">
<column name="groupid" length="32" not-null="true" />
</many-to-many>
</set>
2、說說爲什麼使用OpenSessionInView
當hibernate+spring配合使用的時候,如果設置了lazy=true,那麼在讀取數據的時候,當讀取了父數據後,hibernate會自動關閉session,這樣,當要使用子數據的時候,系統會拋出lazyinit的錯誤,這時就需要使用spring提供的 OpenSessionInViewFilter,
OpenSessionInViewFilter主要是保持Session狀態知道request將全部頁面發送到客戶端,這樣就可以解決延遲加載帶來的問題
3、說說struts2中使用OpenSessionInView的注意事項
1、OpenSessionInViewFilter要在Webwork的filter前面,否則系統會報錯。
2、對於OpenSessionInView的配置中,singleSession應該設置爲true,表示一個request只能打開一個 session,如果設置爲false的話,session可以被打開多個,這時在update、delete的時候會出現打開多個session的異常。但是當設置爲true的時候,系統的性能會因爲用戶的網絡狀況受到影響,當request在生成頁面完成後,session纔會被釋放,所以如果用戶的網絡狀況比較差,那麼連接池中的鏈接會遲遲不被回收,造成內存增加,系統性能受損。但是如果不用這種方法的話,lazy模式有體現不出它的優點。singleSession默認爲true,若設爲false則等於沒用OpenSessionInView 。所以默認可以不寫 。
3、只有在spring中配置了事物才能在web.xml配置openSessionInViewFilter否則會出錯, dao層的類都要繼承於 HibernateDaoSupport
web.xml配置:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>s2sh</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>*.action</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
</web-app>
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<filter>
<filter-name>openSessionInViewFilter</filter-name>
<filter-class>
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
</filter-class>
<init-param>
<param-name>singleSession</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>openSessionInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>struts2</filter-name>
<filter-class>
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
4、在沒有使用Spring提供的Open Session In View情況下,因需要在service(or Dao)層裏把session關閉,所以lazy loading 爲true的話,要在應用層內把關係集合都初始化,如 company.getEmployees(),否則Hibernate拋session already closed Exception;
4、OpenSessionInViewInterceptor 配置
OpenSessionInViewInterceptor和OpenSessionInViewFilter,功能相同,只是一個在web.xml配置,另一個在application.xml配置而已。 <bean name="openSessionInViewInterceptor"
class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor">
<property name="sessionFactory">
<ref bean="sessionFactory" />
</property>
</bean>
<!-- 只是用於springMVC -->
<bean id="urlMapping"
class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="interceptors">
<list>
<ref bean="openSessionInViewInterceptor" />
</list>
</property>
</bean>