• Spring-Hibernate-web的延迟加载方案


    1,现象与问题

         /**
         * 由于Hibernate存在延迟加载问题,当Dao事务提交之后,session就关闭;
         * 此时如果到显示层就没有办法获取对象,使用openSessionInViewer是解决延迟加载的方案
         *
         * 解决思路:
         * 1,在表示层开启session
    * 需要在表示层获取Spring工厂,以此获取Hibernate的SessionFactory * 2,在dao层获取表示层的session
    * 如果希望在Dao层获取表示层的数据,应该将要获取的数据存储到ThreadLocal中 * 3,当这个过程执行完毕之后再关闭session * * 需要使用Filter解决这个问题
    */

    2, 步骤

      创建一个SessionFilter类

        /**
         * 在过滤器初始化方法中进行Spring工厂,sessionFactory的初始化操作
         */
        public void init(FilterConfig cfg) throws ServletException {
            //这个是很重要的方法
            wac=WebApplicationContextUtils.getWebApplicationContext(cfg.getServletContext());
            sessionFactory=(SessionFactory) wac.getBean("sessionFactory");
        }

      通过ThreadLocal处理session

    private static ThreadLocal<Session> sessionHolder= new ThreadLocal<Session>();
        
        //setSession()方法只会在这个方法中使用
        private static void setSession(Session session){
            sessionHolder.set(session);
        }
        public static Session getSession(){
            return sessionHolder.get();    
        }
        private static void removeSession(){
            sessionHolder.remove();
        }

     在web.xml中配置该Filter

        <!-- 配置openSessionInViewFilter-->
        <filter>
            <filter-name>openSessionInViewFilter</filter-name>
            <filter-class>com.yangw.spring.filter.OpenSessionFilter</filter-class>
        </filter>
        
        <filter-mapping>
            <filter-name>openSessionInViewFilter</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>

    比如在BaseDao中的使用 

          public List<T> list(String hql, Object[] args) {
            
            /**
             * 如果使用了自定的OpenSessionFilter,需要安装如下方式获取
             */
            Query query=OpenSessionFilter.getSession().createQuery(hql);
            //Query query=this.getSession().createQuery(hql);
            if(args!=null){
                for(int i=0;i<args.length;i++){
                    query.setParameter(i, args[i]);
                }
                
            }//    return listToBean(query.list(),hql);
            return query.list();
        }

    说了这么多,其实Spring就有OpenSessionInViewFilter ,我们只需要在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">
      
         <!-- 1,创建Spring的监听器-->
         <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
        <!-- 2, Spring的监听器通过context-param获取beans.xml的位置-->
        <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath*:beans.xml</param-value>
        </context-param>
        
        <!-- 配置openSessionInViewFilter-->
        <!-- 如果把这个Filter放到struts2之后,所有的请求都会被struts2所控制,这个Filter就不起作用,必须将这个Filter放到struts2之前 -->
        <!-- Spring提供了OpenSessionInViewFilter,我们在web.xml配置即可,以前代码怎么写还是怎么写,不需要任何变化-->
        
        <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,配置struts2的过滤器-->
        <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>
        @SuppressWarnings("unchecked")
    
        public List<T> list(String hql, Object[] args) {
            
            //select * 的处理,可以利用反射来做
            /**
             * 如果使用了自定的OpenSessionFilter,需要安装如下方式获取
             */
            //Query query=OpenSessionFilter.getSession().createQuery(hql);
            /**
             * 如果使用Spring提供的OpenSessionFilter,代码不需要任何变化
             */
            Query query=this.getSession().createQuery(hql);
            if(args!=null){
                for(int i=0;i<args.length;i++){
                    query.setParameter(i, args[i]);
                }
                
            }//    return listToBean(query.list(),hql);
            return query.list();
        }
    ----------- 赠人玫瑰,手有余香     如果本文对您有所帮助,动动手指扫一扫哟   么么哒 -----------


    未经作者 https://www.cnblogs.com/xin1006/ 梦相随1006 同意,不得擅自转载本文,否则后果自负
  • 相关阅读:
    SQL里面的函数应用
    Split的小用法
    堆栈和堆问题
    break,continue,goto,Return几个方法
    接口笔记
    抽象类
    虚方法
    将博客搬至CSDN
    运行数据区
    美团-走迷宫
  • 原文地址:https://www.cnblogs.com/xin1006/p/3387679.html
Copyright © 2020-2023  润新知