注册本站  论坛  繁體中文

电脑技巧
手机 | MP3 | MP4 | 显卡 | 主板 | 显示器 | 光存储 | 笔记本 | 网络设备 | 移动存储 | 数码相机
键鼠 | CPU | 音箱 | GPS | 电视 | 服务器 | 投影机 | 机箱电源 | 品牌电脑 | 办公打印 |
| 网站首页 | Cisco | Windows | Linux | Java | Dotnet | Oracle | 网页设计 | 平面设计 | 安全 | 软件应用 | 电脑维修 | 办公维修 |
您现在的位置: 电脑技巧 >> Java >> 开源技术 >> Hibernate >> Java正文

利用ThreadLocal绑定Hibernate的session

文章来源:中国IT实验室收集整理 作者:佚名 更新时间:2008-6-28 20:35:37 【 】 【加入收藏

    无论是立即加载还是延迟加载必须要连接数据库的,而在java中连接数据库是依赖java.sql.Connection,在hibernate中session就是Connection的一层高级封装,一个session对应了一个Connection,要实现延迟加载必须有session才行.而且要进行延迟加载还必须保证是同一个session才行,用另外一个session去延迟加载前一个session的代理对象是不行的.大家都知道Connection是使用过后必须要进行关闭的,那么我们如何保证一次http请求过程中,一直都使用一个session呢,即一个Connection呢.而且还要保证http请求结束后正确的关闭.

    好,现在我们知道了我们要解决的问题

    1.如何保证http请求结束后正确的关闭session

    2.如何保证http请求过程中一直使用同一个session

    第一个问题很容易想到,使用过滤器

    view plaincopy to clipboardprint?
    public void doFilter(ServletRequest request, ServletResponse response,

            FilterChain filterChain) {

        try {

            filterChain.doFilter(request, response);

        } catch (IOException e) {

            e.printStackTrace();

        } catch (ServletException e) {

            e.printStackTrace();

        } finally {

            try {

                HibernateUtil.commitTransaction();

            } catch (Exception e) {

                HibernateUtil.rollbackTransaction();

            } finally {

                HibernateUtil.closeSession();

            }

        }

    }

     public void doFilter(ServletRequest request, ServletResponse response,

       FilterChain filterChain) {

      try {

       filterChain.doFilter(request, response);

      } catch (IOException e) {

       e.printStackTrace();

      } catch (ServletException e) {

       e.printStackTrace();

      } finally {

       try {

        HibernateUtil.commitTransaction();

       } catch (Exception e) {

        HibernateUtil.rollbackTransaction();

       } finally {

        HibernateUtil.closeSession();

       }

      }

     }要解决第二个问题我们必须先搞清楚,http请求在java中是以什么样的机制实现的,在java中一个请求就是一个线程,像流行的web容器Tomcat等,往往都是采用线程池机制的也就是说有n个线程在池子里面,每当有http请求时,随机从线程池中取出一个线程对象去处理请求,实际上多次请求可能使用的是同一线程也可能不是,这是随机的.要保证整个请求中使用同一session最容易想到的就是把这个session绑定到线程上,在java中使用ThreadLocal可以轻松绑定变量,每个线程有一个自己的ThreadLocal,这个ThreadLocal会随线程的销毁一起销毁,既然是每个线程有一个那么多个线程间自然是不会有影响了,所以把session绑定在ThreadLocal里面是最好的选择了,

    有关ThreadLocal的更多资料,大家可以百度或者参考

    http://www-128.ibm.com/developerworks/cn/java/j-threads/index3.html

    http://www.blogjava.net/jspark/archive/2006/08/01/61165.html

    最后我把相关的代码发出来

    view plaincopy to clipboardprint?
    import java.sql.SQLException;

    import org.hibernate.HibernateException;

    import org.hibernate.Session;

    import org.hibernate.SessionFactory;

    import org.hibernate.Transaction;

    import org.hibernate.cfg.Configuration;

    import java.sql.Connection;

    import org.apache.log4j.Logger;

    import java.io.File;

 

    /**

     *

     * <p>

     * Title:Hibernate工具类

     * </p>

     *

     * <p>

     * 利用ThreadLocal 绑定 Hibernate 的session

     * </p>

     *

     * @author 孙钰佳

     * @mail sunyujia@yahoo.cn

     * @version 1.0

     */

    public class HibernateUtil {

        /**

         * Loger4j的logger

         */

        private static final Logger logger = Logger.getLogger(HibernateUtil.class);

        /**

         * 存储hibernate session的ThreadLocal

         */

        private static final ThreadLocal sessionThread = new ThreadLocal();

        /**

         * 存储事务的ThreadLocal

         */

        private static final ThreadLocal transactionThread = new ThreadLocal();

        /**

         * Hibernate 的 Session工厂

         */

        private static SessionFactory sessionFactory = null;

 

        /**

         * 初始化SessionFactory

         *

         * @param file

         *            Hibernate配置文件

         */

        public static void initSessionFactory(File file) {

            Configuration config = new Configuration();

            config.configure(file);

            sessionFactory = config.buildSessionFactory();

        }

 

        /**

         * 获取当前线程绑定的session

         *

         * @return Session

         * @throws HibernateException

         */

        public static Session getSession() {

            Session s = (Session) sessionThread.get();

            if (s == null) {

                s = sessionFactory.openSession();

                sessionThread.set(s);

            } else {

                Connection conn = s.connection();

                try {

 

                    if (conn == null || conn.isClosed()) {

                        try {

                            s.close();

                        } catch (HibernateException e) {

                            logger.warn("close session error:" + e.getMessage(), e);

                        }

                        s = sessionFactory.openSession();

                        sessionThread.set(s);

                    }

                } catch (SQLException e) {

                    throw new HibernateException(e);

                }

            }

            return s;

        }

 

        /**

         * 取得当前session的事务

         *

         * @return Transaction

         */

        public static Transaction transaction() {

            Transaction transaction = (Transaction) transactionThread.get();

            if (transaction == null) {

                transaction = getSession().beginTransaction();

                transactionThread.set(transaction);

            }

            return transaction;

        }

 

        /**

         * 提交当前session的事务

         */

        public static void commitTransaction() {

            Transaction transaction = (Transaction) transactionThread.get();

            transactionThread.set(null);

            if (transaction != null)

                transaction.commit();

        }

 

        /**

         * 回滚当前session的事务

         */

        public static void rollbackTransaction() {

            Transaction tx = (Transaction) transactionThread.get();

            transactionThread.set(null);

            if (tx != null)

                tx.rollback();

        }

 

        /**

         * 关闭当前线程使用的session

         */

        public static void closeSession() {

            Session session = (Session) sessionThread.get();

            if (session != null) {

                session.clear();

                session.close();

                sessionThread.set(null);

            }

        }

    }

    import java.sql.SQLException;

    import org.hibernate.HibernateException;

    import org.hibernate.Session;

    import org.hibernate.SessionFactory;

    import org.hibernate.Transaction;

    import org.hibernate.cfg.Configuration;

    import java.sql.Connection;

    import org.apache.log4j.Logger;

    import java.io.File;

 

    /**

     *

     * <p>

     * Title:Hibernate工具类

     * </p>

     *

     * <p>

     * 利用ThreadLocal 绑定 Hibernate 的session

     * </p>

     *

     * @author 孙钰佳

     * @mail sunyujia@yahoo.cn

     * @version 1.0

     */

    public class HibernateUtil {

     /**

      * Loger4j的logger

      */

     private static final Logger logger = Logger.getLogger(HibernateUtil.class);

     /**

      * 存储hibernate session的ThreadLocal

      */

     private static final ThreadLocal sessionThread = new ThreadLocal();

     /**

      * 存储事务的ThreadLocal

      */

     private static final ThreadLocal transactionThread = new ThreadLocal();

     /**

      * Hibernate 的 Session工厂

      */

     private static SessionFactory sessionFactory = null;

 

     /**

      * 初始化SessionFactory

      *

      * @param file

      *            Hibernate配置文件

      */

     public static void initSessionFactory(File file) {

      Configuration config = new Configuration();

      config.configure(file);

      sessionFactory = config.buildSessionFactory();

     }

 

     /**

      * 获取当前线程绑定的session

      *

  

    * @return Session

      * @throws HibernateException

      */

     public static Session getSession() {

      Session s = (Session) sessionThread.get();

      if (s == null) {

       s = sessionFactory.openSession();

       sessionThread.set(s);

      } else {

       Connection conn = s.connection();

       try {

        if (conn == null || conn.isClosed()) {

         try {

          s.close();

         } catch (HibernateException e) {

          logger.warn("close session error:" + e.getMessage(), e);

         }

         s = sessionFactory.openSession();

         sessionThread.set(s);

        }

       } catch (SQLException e) {

        throw new HibernateException(e);

       }

      }

      return s;

     }

 

     /**

      * 取得当前session的事务

      *

      * @return Transaction

      */

     public static Transaction transaction() {

      Transaction transaction = (Transaction) transactionThread.get();

      if (transaction == null) {

       transaction = getSession().beginTransaction();

       transactionThread.set(transaction);

      }

      return transaction;

     }

 

     /**

      * 提交当前session的事务

      */

     public static void commitTransaction() {

      Transaction transaction = (Transaction) transactionThread.get();

      transactionThread.set(null);

      if (transaction != null)

       transaction.commit();

     }

 

     /**

      * 回滚当前session的事务

      */

     public static void rollbackTransaction() {

      Transaction tx = (Transaction) transactionThread.get();

      transactionThread.set(null);

      if (tx != null)

       tx.rollback();

     }

 

     /**

      * 关闭当前线程使用的session

      */

     public static void closeSession() {

      Session session = (Session) sessionThread.get();

      if (session != null) {

       session.clear();

       session.close();

       sessionThread.set(null);

      }

     }

    }

 

    下面是一个调用的例子: view plaincopy to clipboardprint?
    public static void main(String[] args) throws Exception {

        HibernateUtil.initSessionFactory(new File(Test.class.getClassLoader()

                .getResource("hibernate.cfg.xml").getFile()));

        Session session = HibernateUtil.getSession();

        HibernateUtil.transaction();

        User u = new User();

        u.setName("test");

        session.save(u);

        HibernateUtil.commitTransaction();

        HibernateUtil.closeSession();

    }

  • 上一篇Java:

  • 下一篇Java:
  • 最 新 热 门
     手机开发平台指南、教程和资料介绍
     关于什么叫面向接口编程
     编写高级JavaScript应用代码
     不要验证,直接转化科学计数法
     Eclipse插件开发中实现刷新和重编译介绍
     Java开源技术:Eclipse的使用技巧详解
     配置eclipse 3.2 使用JDK1.5中文JavaAPI
     集成Windows本地应用到Eclipse RCP 程序中
     hibernate.cfg.xml配置文件的说明
     eclipse开发jface时,main.class解决方法
    最 新 推 荐
     从Hibernate的映射谈编程思想
     JSF和Hibernate的比较
     hibernate的核心接口
     利用ThreadLocal绑定Hibernate的session
     Struts2 Spring Hibernate 的简单整合
     在Hibernate中创建安全Session
     hibernate在sql server下分页的处理
     hibernate3二级缓存的配置及测试
     Hibernate一对多双向映射及乐观锁使用
     Java开发中关于Hibernate对多表关联查询
    相 关 文 章

    Struts2利用stream直接输出Excel
    Heritrix的多线程ToeThread和ToePool
    利用Ecipse生成Javadoc乱码解决方法
    利用 Ant 和 JUnit 进行增量开发
    直接利用weblogic 发布的数据源
    JavaFX Script With Eclipse
    利用Axis在Java平台上部署WebService
    如何利用JAVA实现斐波那契数
    如何利用Java编写ASP组件
    解决AIX配置tomcat https出现的问题

    | 设为首页 | 加入收藏 | 联系站长 | 友情链接 | 版权申明 | 网站公告

     

    Copyright 2006-2008 pcjx.com All Rights Reserved
    电脑技巧 版权所有 粤ICP备06059145号 地图
    本网站所有内容未经许可不得转载或做其他使用