`
Callan
  • 浏览: 735910 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

利用过滤器对hibernate的session管理,实现session在线程范围内的共享

    博客分类:
  • Java
阅读更多
hibernate中的Session关系到对数据库的增删查改等基本的数据存取操作.对Session进行有效的维护,就像是在jdbc编程中对JDBC collection的维护.
     在struts+hibernate的方案中,常常利用过滤器(Filter)对session进行管理,以实现session在线程范围内的共享.为什么仅仅实现线程内的共享,是因为,不能把session用于多线程,否则会出现意外.在线程范围内实现sesion的共享.避免了session的频繁的创建和销毁.我看到有的程序中,在单个方法内,打开session,执行.关闭session.这显然没有在一次会话中有效的利用session
     下面的方案是.通过建立一个过滤器,以实现对sesion的共享:
package com.cs_oj.filter;

import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

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 javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Session;
import org.hibernate.Transaction;


import com.cs_oj.data.dao.HibernateSessionFactory;

public class HibernateSessionFilter implements Filter {
    private static final Log log = LogFactory.getLog(HibernateSessionFilter.class);
    public void destroy() {
        // TODO Auto-generated method stub

    }

    public void doFilter(ServletRequest arg0, ServletResponse arg1,
            FilterChain chain) throws IOException, ServletException {
        log.debug("HibernateSessionFilter start");
        Date date=new Date();
        DateFormat df=new SimpleDateFormat("yyyy-MM-dd '时间--'HH:mm:ss");
        System.out.println("----当前时间:"+df.format(date)+"----");
        System.out.println("----------HibernateSessionFilter start-----------");

//利用HibernateSessionFactory, 得到当 前线程中的session对象..HibernateSessionFactory的代码利用了ThreadLocal模式..详见..HibernateSessionFactory
        Session session=HibernateSessionFactory.getSession(); 
        log.info("HibernateSessionFilter begin transaction");
        System.out.println("HibernateSessionFilter begin transaction");
       Transaction tx=session.beginTransaction();   //开始事务
        
        log.debug("HibernateSessionFilter begin doChain");
        HttpServletResponse response=(HttpServletResponse)arg1;
        try{
            chain.doFilter(arg0, arg1);
            
            log.debug("HibernateSessionFilter begin commit");
            //没有异常,则提交
            try{
                
                System.out.println("HibernateSessionFilter begin commit");
                tx.commit();
                System.out.println("HibernateSessionFilter commit success");
                
            }
            catch(Exception e){
                
                System.out.println("HibernateSessionFilter commit failed");
                System.out.println("HibernateSessionFilter begin rollback() ");
                try{
                    System.out.println("HibernateSessionFilter begin rollback() ");
                    tx.rollback();
                    System.out.println("HibernateSessionFilter rollback() success ");
                }catch(RuntimeException ex){
                    System.out.println("HibernateSessionFilter   rollback() failed");
                }
            }
        }catch (Exception e) {
            e.printStackTrace();
            System.out.println("chain.doFilter(arg0, arg1) exception accurs ");
            System.out.println("HibernateSessionFilter begin rollback() ");
            tx.rollback();   //出现异常,回滚
            //response.sendRedirect("error.jsp");
        }
        finally{
            log.debug("HibernateSessionFilter end doChain");
            System.out.println("HibernateSessionFilter begin close session");
           HibernateSessionFactory.closeSession();
            System.out.println("*********HibernateSessionFilter close session success*********");
            log.debug("HibernateSessionFilter begin close session");
            //System.out.println("session.isOpen()="+session.isOpen());
        }

    }

}

 

 

 

在web.xml文件中对上面的过滤器进行配置.

<filter>
    <filter-name>hibernateSession</filter-name>
    <filter-class>com.cs_oj.filter.HibernateSessionFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>hibernateSession</filter-name>
    <servlet-name>action</servlet-name>
   
</filter-mapping>
<servlet>
    <servlet-name>action</servlet-name>
    <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
    <init-param>.
    <init-param>
      <param-name>config</param-name>
      <param-value>/WEB-INF/struts-config.xml</param-value>
    </init-param>
    <init-param>
      <param-name>debug</param-name>
      <param-value>3</param-value>
    </init-param>
    <init-param>
      <param-name>detail</param-name>
      <param-value>3</param-value>
    </init-param>
    <load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>action</servlet-name>
    <url-pattern>*.do</url-pattern>
</servlet-mapping>

 

 

则对所有以.do作为后缀名的url,都会被过滤器过滤.在被过滤器过滤的action中,和业务层的方法内,只需要调用HibernateSessionFactory 的getSession()方法,得到当前线程内的session对象.用完session后,不要关闭session,而且,每次在用session进行添加和修改操作时,也不需要启动事务.

 

 

HibernateSessionFactory.java

 

package com.cs_oj.data.dao;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.cfg.Configuration;


public class HibernateSessionFactory {

    /** 
     * Location of hibernate.cfg.xml file.
     * Location should be on the classpath as Hibernate uses 
     * #resourceAsStream style lookup for its configuration file. 
     * The default classpath location of the hibernate config file is 
     * in the default package. Use #setConfigFile() to update 
     * the location of the configuration file for the current session.   
     */
    private static String CONFIG_FILE_LOCATION = "/hibernate.cfg.xml";
    private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
    private static Configuration configuration = new Configuration().configure();
    private static org.hibernate.SessionFactory sessionFactory;
    private static String configFile = CONFIG_FILE_LOCATION;

    private HibernateSessionFactory() {
    }
    
    /**
     * Returns the ThreadLocal Session instance. Lazy initialize
     * the <code>SessionFactory</code> if needed.
     *
     * @return Session
     * @throws HibernateException
     */
    public static Session getSession() throws HibernateException {
        Session session = threadLocal.get();

        if (session == null || !session.isOpen()) {
            if (sessionFactory == null) {
                rebuildSessionFactory();
            }
            session = (sessionFactory != null) ? sessionFactory.openSession()
                    : null;
            threadLocal.set(session);
        }

        return session;
    }

    /**
     * Rebuild hibernate session factory
     *
     */
    public static void rebuildSessionFactory() {
        try {
            //configuration.configure();
            sessionFactory = configuration.buildSessionFactory();
        } catch (Exception e) {
            System.err
                    .println("%%%% Error Creating SessionFactory %%%%");
            e.printStackTrace();
        }
    }

    /**
     * Close the single hibernate session instance.
     *
     * @throws HibernateException
     */
    public static void closeSession() throws HibernateException {
        Session session = threadLocal.get();
        threadLocal.set(null);

        if (session != null) {
            session.close();
        }
    }

    /**
     * return session factory
     *
     */
    public static org.hibernate.SessionFactory getSessionFactory() {
        return sessionFactory;
    }

    /**
     * return session factory
     *
     *    session factory will be rebuilded in the next call
     */
    public static void setConfigFile(String configFile) {
        HibernateSessionFactory.configFile = configFile;
        sessionFactory = null;
    }

    /**
     * return hibernate configuration
     *
     */
    public static Configuration getConfiguration() {
        return configuration;
    }

}

 

分享到:
评论
1 楼 jasstion 2010-04-16  
大榭!哎,怎么我就没有想到用过滤器实现类似于Spring中的AOP方式对于事物的自动提交!!!这样不仅实现啦数据库事物的自动提交而且好实现了长事务实!

相关推荐

    Hibernate事务管理.

    Hibernate事务管理是数据库操作中的关键部分,尤其是在使用ORM(对象关系映射)框架如Hibernate时。事务管理确保了数据的一致性和完整性,防止在并发环境中出现数据不一致的情况。在没有Spring提供的Open Session In...

    SSH整合 struts+hibernate+spring

    - 在Web应用的拦截器或过滤器中打开Session,并将其绑定到线程中。 - 在请求结束时关闭Session。 - 通过这种方式,可以确保所有的数据库操作都在同一个Session中完成,提高了性能。 #### 五、Struts与Spring的...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part2

     21.5 利用Hibernate的版本控制来实现乐观锁  21.5.1 使用元素  21.5.2 使用元素  21.5.3 对游离对象进行版本检查  21.5.4 强制更新版本  21.6 实现乐观锁的其他方法  21.7 小结  21.8 思考题 第22章 管理...

    hibernate面试题总结

    - **OpenSessionInView**:是一种设计模式,用于Web应用中,通过过滤器在请求开始时打开`Session`,结束时关闭,确保整个请求过程中`Session`可用,从而支持延迟加载。但这种方法可能导致过多的数据库连接,因此也...

    struts+hibernate技术整合开发的网上书店

    Struts和Hibernate是两种在Java Web开发中广泛使用的开源框架,它们分别负责表现层和持久层的管理。Struts作为MVC(Model-View-Controller)框架,主要用于处理用户请求和控制应用程序流程,而Hibernate则是一个对象...

    hibernate学习文档

    在 Hibernate 中,ORM 的实现主要包括以下几个方面: - **实体类**:表示数据库表中的一行数据,通常一个表对应一个实体类。 - **Session**:Hibernate 提供的用于操作数据库的基础接口,负责执行 CRUD 操作。 - **...

    Hibernate实战(第2版 中文高清版)

    第一部分 从Hibernate和EJB 3.0开始  第1章 理解对象/关系持久化   1.1 什么是持久化   1.1.1 关系数据库   1.1.2 理解SQL   1.1.3 在Java中使用SQL   1.1.4 面向对象应用程序中的持久化   1.2 范式不...

    Hibernate学习.pdf

    - **Session**: Hibernate进行所有数据库操作的基本上下文环境,是线程不安全的,每次操作都应打开新的Session,并在操作完成后关闭它。 - **Transaction**: 事务控制。 - **Query**: 查询操作。 - **Configuration*...

    struts2和hibernate整合

    3. **Hibernate Session和SessionFactory**:在Hibernate中,SessionFactory是线程安全的,用于创建Session实例。Session是与数据库交互的主要接口,用于执行CRUD操作。 4. **实体类和映射文件**:Hibernate通过XML...

    Spring+Hibernate下的数据库连接动态切换

    过滤器可以在每次请求到达前读取用户的会话信息,并根据其中的信息设置当前线程绑定的数据源。 - **线程局部变量(ThreadLocal)**:使用`ThreadLocal`来存储当前线程的数据源信息,确保每个线程的操作都针对正确的...

    hibernate_PPT 教程

    最后,本教程可能还会涉及Hibernate的其他高级特性,如延迟加载(Lazy Loading)、级联操作(Cascade)、过滤器(Filters)和事件监听器(Listeners)等,这些都是在实际开发中非常实用的功能。 总的来说,这份...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part4

     21.5 利用Hibernate的版本控制来实现乐观锁  21.5.1 使用元素  21.5.2 使用元素  21.5.3 对游离对象进行版本检查  21.5.4 强制更新版本  21.6 实现乐观锁的其他方法  21.7 小结  21.8 思考题 第22章 管理...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part3

     21.5 利用Hibernate的版本控制来实现乐观锁  21.5.1 使用元素  21.5.2 使用元素  21.5.3 对游离对象进行版本检查  21.5.4 强制更新版本  21.6 实现乐观锁的其他方法  21.7 小结  21.8 思考题 第22章 管理...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part1.rar

     21.5 利用Hibernate的版本控制来实现乐观锁  21.5.1 使用元素  21.5.2 使用元素  21.5.3 对游离对象进行版本检查  21.5.4 强制更新版本  21.6 实现乐观锁的其他方法  21.7 小结  21.8 思考题 第22章 管理...

    Struts2+Hibernate整合实例

    - 为了确保线程安全,应在每次请求时获取新的Session实例,而不是在整个应用程序生命周期内共享一个SessionFactory。 - 结果集可以通过ModelDriven或ValueStack传递到视图层,方便渲染。 4. **使用Interceptor**...

    [尚硅谷]_佟刚_Hibernate面试题分析

    以上知识点覆盖了Hibernate的核心概念和操作,面试中涉及到这些内容时,应聘者应能清晰地表达对Hibernate框架的理解和使用经验,特别是在检索方式、对象状态管理、缓存机制以及性能优化方面的知识。此外,对 ...

    hibernate二级缓存

    一级缓存是每个Hibernate Session内的内存缓存,它是默认开启的,并且线程安全。当一个对象被加载到Session时,它会被放入一级缓存中,同一Session内的后续查询会优先从缓存中获取数据,而不是重新查询数据库。 二...

    深入浅出Hibernate

    以上只是Hibernate众多特性和功能的一部分,实际上,Hibernate还包括了类型转换、事件监听、过滤器、查询优化等更多高级特性。《深入浅出Hibernate》这本书详细介绍了这些内容,通过阅读,读者可以全面掌握Hibernate...

    hibernate zh-CN(详情看资源描述)

    解决方法是在Web应用的过滤器中设定响应头的编码,如下所示: ```java response.setContentType("text/html;charset=UTF-8"); ``` 此外,确保项目的编码设置也是UTF-8,包括IDE、源代码、HTML页面等。对于数据库中...

    SpringMvc(4.0)+hibernate(4.0)

    在这个项目中,Hibernate 4.0 被用来管理数据库操作,包括创建、读取、更新和删除(CRUD)数据,通过 Session 和 Transaction API 进行事务处理。 【项目结构】 项目结构通常包含以下几个部分: 1. src/main/java:...

Global site tag (gtag.js) - Google Analytics