在任何地方获取多数据源hibernate session 的方法

原理:基于threadLocal:

使用hibernate,我们最终要获得的是一个hibernate session对象,

在第一次使用到一个hibernate Session的时候,创建创建一个session,并将其存储到threadLocal map集合中。

在同一个请求中,如果我们还需要用到这个session.我们就可以从threadLocal map集合中获取到这个session.接着使用。

在请求结束时(可以使用filter),关闭并清除ThreadLocal Map 中的所有session对象。

优点:可以配置多个数据源;可以在一个请求中在任何地方获取到hibernate session 对象;无需手工关闭hibernate session对象。

缺点:hibernate session 存活时间较长;我没详细测试过,只是理论上可行。

下面是代码:

1 HSessionHolder.java:用于获取到对应的session.

package com.hf.hibernate.util;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.apache.log4j.Logger;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

/**
 *
 * @author Administrator
 *
 */
public class HSessionHolder {
 private static Logger logger = Logger.getLogger(HSessionHolder.class);
   /**
    * threadLocal集合,对应了不同的配置文件
    */
   private static Map <String ,ThreadLocal<Session>>    threadLocalMap      =new HashMap <String ,ThreadLocal<Session>>();
   /**
    * 配置文件名称-路径集合
    */
   private static Map <String ,String>    configFileLocationMap      =new HashMap <String ,String>();
  
   /**
    * Hibernate SessionFactory 名称-对象集合
    */
   private static Map <String ,SessionFactory>    sessionFactoryMap      =new HashMap <String ,SessionFactory>();
   /**
    * hibernate配置文件读取器
    */
   private static final Configuration cfg    = new Configuration();
   /**
    *
    */
   private static final String DEFAULT_FLAG     = "configOne";
   /**
    * 初始化配置文件集合
    */
   static {
     /**
      * 初始化配置文件集合
      */
    String configOneFlag="configOne";
    String configOnePath="/com/hf/hibernate/config/hibernate.cfg.xml";
    configFileLocationMap.put(configOneFlag,configOnePath);
    /**
      * 初始化threadLocalMap集合
    */
    ThreadLocal<Session> configOneT = new ThreadLocal<Session>();
    threadLocalMap.put(configOneFlag,configOneT);
   
    /**
     * 初始化各个sessionFactory对象
     */
    Iterator configIterator =configFileLocationMap.keySet().iterator();
    while(configIterator.hasNext()){
     String configFlag = (String) configIterator.next();
     String configPath = configFileLocationMap.get(configOneFlag);
    
    
     cfg.configure(configPath);
           SessionFactory sessionFactory = cfg.buildSessionFactory();
           sessionFactoryMap.put(configFlag, sessionFactory);
    }
   
   
  }//static
  
   /**
    * 获取默认数据库的会话对象
    * @param flag
    * @return
    */
   public static Session getSession() {
    String flag= DEFAULT_FLAG;
    return getSession(flag);
  
   }
  
   /**
    * 关闭所有可能已经打开的hibernate会话
    * @return
    */
   public static void closeSessions() {
    /**
     * 遍历所有的threadLocalMap的成员,如果存在Session,则关掉。
     */
    Iterator<String> threadLocalIterator =threadLocalMap.keySet().iterator();
    while(threadLocalIterator.hasNext()){
     ThreadLocal<Session> t =threadLocalMap.get(threadLocalIterator.next());
     Session session = t.get();
     if(session!=null){
      session.close();
      t.set(null);
      logger.info("成功的关闭了一个hibernate Session,并清空ThreadLocal");
     }
    
    }
   }
  
   /**
    * 获取制定数据库的会话对象
    * @param flag
    * @return
    */
   public static Session getSession(String flag) {
    /**
     * 取到threadLocal
     */
    ThreadLocal<Session> t = threadLocalMap.get(flag);
    if(t==null){
     try {
   throw new Exception("无效的threadlocal 标志");
     } catch (Exception e) {
   // TODO 自动生成 catch 块
   e.printStackTrace();
     }
  return null;
    }
    /**
     * 看看里面是不是已经有session了
     */
    Session session = (Session) threadLocalMap.get(flag).get();
    /**
     * 没有的话创建一个新的
     */
    if (session == null || !session.isOpen()) {
     SessionFactory sessionFactory = sessionFactoryMap.get(flag);
        if (sessionFactory != null) {
         
             session = sessionFactory.openSession();
            
          }
        /**
         * 将session存入threadLocal
         */
          t.set(session);
       }
       return session;
 }

  
}

2 filter:HSessionFilter :在结束时关闭所有打开的hibernate session

package com.hf.hibernate.filter;

import java.io.IOException;

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 org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.hf.hibernate.util.HSessionHolder;


public class HSessionFilter implements Filter {

   private static final Log   log = LogFactory .getLog(HSessionFilter.class);

  


   public void init(FilterConfig config) throws ServletException {
    
   }

 /**
  * 此过滤器只在最终关闭掉所有打开的session就可以了。
  */
   public void doFilter(ServletRequest request, ServletResponse response,
         FilterChain chain) throws IOException, ServletException {

      try {
         chain.doFilter(request, response);
      } finally {
       HSessionHolder.closeSessions();
      }
   }

   public void destroy() {}
}

 

使用方法:

例如在一个DAO的保存方法中:

/**
  * 保存信息分类对象到数据库中,已经设置好了id了
  * @return
  */
 public static boolean save(Info category) {
   log.info("开始进行保存分类信息操作");
  /*获取到hibernate session,这里调用的是默认的数据库配置*/
   Session session = HSessionHolder.getSession();
  /*开启事务*/
  Transaction tran = session.beginTransaction();
  try {
   session.save(category);
   tran.commit();
   
  } catch (Exception e) {

//这里应该增加回退功能
      e.printStackTrace();
   return false;
  }
        return true;
 }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值