Chinaunix首页 | 论坛 | 博客
  • 博客访问: 596274
  • 博文数量: 765
  • 博客积分: 40000
  • 博客等级: 大将
  • 技术积分: 5005
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-16 18:49
文章分类

全部博文(765)

文章存档

2011年(1)

2008年(764)

我的朋友

分类:

2008-10-16 18:55:50

    无论是立即加载还是延迟加载必须要连接数据库的,而在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的更多资料,大家可以百度或者参考

   

   

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

    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;

 

    /**

     *

     *

     * Title:Hibernate工具类

     *

     *

     *

     * 利用ThreadLocal 绑定 Hibernate 的session

     *

     *

     * @author 孙钰佳

     * @mail

     * @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 {

 

[1]   

【责编:landy】

--------------------next---------------------

阅读(260) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~