OpenSessionInViewInview是什麼? OpenSessionInViewFilter是Spring提供的一個針對Hibernate的一個支持類
其主要意思是在發起一個頁面請求時打開Hibernate的Session
一直保持這個Session
直到這個請求結束
具體是通過一個Filter來實現的
當然
在我的理解
OpenSessionInView是Hibernate的一種模式
因為官方也給出了相關代碼
JBoss的OpenSessionInView的地址
OpenSessionInView簡單來說
就是在請求到達View時Session不關閉
可以方便的調用Session中的方法
由於Hibernate引入了Lazy特性
使得脫離Hibernate的Session周期的對象如果再想通過getter方法取到其關聯對象的值
Hibernate會拋出一個LazyLoad的Exception
所以為了解決這個問題
Spring和Hibernate都給出了相應的解決方案
Spring的方案是一個過濾器
只需要你配置就OK了
但是
我目前公司的項目用的是單Hibernate一個框架
以前公司未解決懶加載問題
將所有的關聯對象的lazy全部設為false
這樣大大降低了系統的運行效率
為了解決這個問題
自動翻閱資料
找到了Hibernate官方的OpenSessionInView模式
此模式是一個Filter
package mon
hibernate
;import java
io
IOException;import javax
servlet
Filter;import javax
servlet
FilterChain;import javax
servlet
FilterConfig;import javax
servlet
ServletException;import javax
servlet
ServletRequest;import javax
servlet
ServletResponse;import org
hibernate
SessionFactory;import org
hibernate
StaleObjectStateException;/* * Hibernate的OpenSessionInView過濾器
可以實現在頁面中Session依舊不關閉
解決懶加載帶來的副作用
可以隨意使用懶加載
提升系統效率 * * @author wurt * */public class HibernateSessionRequestFilter implements Filter {
private SessionFactory sf;
public void doFilter(ServletRequest request
ServletResponse response
FilterChain chain)
throws IOException
ServletException {
try {
//開啟Session和Transcation
在Hibernate查詢中需要用getCurrentSession獲取當前Session
sf
getCurrentSession()
beginTransaction()
// 放行
chain
doFilter(request
response)
// Session提交
getCurrentSession獲取的Session會在提交之後自動關閉
sf
getCurrentSession()
getTransaction()
commit()
} catch (StaleObjectStateException staleEx) {
throw staleEx;
} catch (Throwable ex) {
// Rollback only
ex
printStackTrace()
try {
//如果Transcation依舊存在
回滾
if (sf
getCurrentSession()
getTransaction()
isActive()) {
sf
getCurrentSession()
getTransaction()
rollback()
}
} catch (Throwable rbEx) {
rbEx
printStackTrace()
}
// Let others handle it… maybe another interceptor for exceptions?
throw new ServletException(ex)
}
}
public void init(FilterConfig filterConfig) throws ServletException {
// sessionFactory
可以通過自己的代碼獲取此值
sf = HibernateSimpleDao
sessionFactory;
}
public void destroy() {} }
將此過濾器配置到web
xml
一切問題都解決了
配制方法如下 <filter>
<filter
name>HibernateSessionInView</filter
name>
<filter
class>mon
hibernate
HibernateSessionRequestFilter</filter
class></filter><filter
mapping>
<filter
name>HibernateSessionInView</filter
name>
<url
pattern>/*</url
pattern></filter
mapping>
然後將公司中Hibernate配置文件的lazy全部去掉
一切OK
之前lazy=
fasle
的情況下
載入Hibernate需要查詢
+甚至更多的SQL
然而采用OpenSessionInView
僅僅需要
條(門戶網站首頁)
為什麼會有這麼大的提升?
之前的SQL是不管用不用
只要是false
全部查出來再說
現在的lazy都是true
在初次查詢時
只會查詢實體需要的字段
而不會查詢關聯的對象
當在View中需要關聯時
才會去查詢數據庫
lazy=true + OpenSessionInView可以避免很多不是必要的查詢
速度自然會有所提升
使用注意事項
在Dao中無需再創建Transcation
因為過濾器已經創建好
使用Session
請使用getCurrentSession來獲取
得到當前的Session
而不是openSession
新建一個Session
通過getCurrentSession獲得的Session無需關閉
因為在過濾器提交時會自動關閉
示例代碼
僅僅貼出一個方法
public List<T> getAll(Class T)
{
Session session = getCurrentSession()
List<T> list = null;
try{
list = session
createQuery(
from
+ T
getName())
list()
return list;
}catch (RuntimeException e){
throw e;
}
}
From:http://tw.wingwit.com/Article/program/Java/hx/201311/26430.html