熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java核心技術 >> 正文

單Hibernate實現OpenSessionInView

2013-11-23 19:12:21  來源: Java核心技術 
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 monhibernate;import javaioIOException;import javaxservletFilter;import javaxservletFilterChain;import javaxservletFilterConfig;import javaxservletServletException;import javaxservletServletRequest;import javaxservletServletResponse;import orghibernateSessionFactory;import orghibernateStaleObjectStateException;/* * 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
   
    sfgetCurrentSession()beginTransaction()
   
    // 放行
   
    chaindoFilter(request response)
   
    // Session提交getCurrentSession獲取的Session會在提交之後自動關閉
   
    sfgetCurrentSession()getTransaction()commit()
   
    } catch (StaleObjectStateException staleEx) {
   
    throw staleEx;
   
    } catch (Throwable ex) {
   
    // Rollback only
   
    exprintStackTrace()
   
    try {
   
    //如果Transcation依舊存在回滾
   
    if (sfgetCurrentSession()getTransaction()isActive()) {
   
    sfgetCurrentSession()getTransaction()rollback()
   
    }
   
    } catch (Throwable rbEx) {
   
    rbExprintStackTrace()
   
    }
   
    // Let others handle it… maybe another interceptor for exceptions?
   
    throw new ServletException(ex)
   
    }
   
    }
   
    public void init(FilterConfig filterConfig) throws ServletException {
   
    // sessionFactory 可以通過自己的代碼獲取此值
   
    sf = HibernateSimpleDaosessionFactory;
   
    }
   
    public void destroy() {} }
   
    將此過濾器配置到webxml一切問題都解決了


   
配制方法如下
   
    <filter>
   
    <filtername>HibernateSessionInView</filtername>
   
    <filterclass>monhibernateHibernateSessionRequestFilter</filterclass></filter><filtermapping>
   
    <filtername>HibernateSessionInView</filtername>
   
    <urlpattern>/*</urlpattern></filtermapping>
   
    然後將公司中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 = sessioncreateQuery(from + TgetName())list()
   
    return list;
   
    }catch (RuntimeException e){
   
    throw e;
   
    } }


From:http://tw.wingwit.com/Article/program/Java/hx/201311/26430.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.