原理:基于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;
}
分享到:
相关推荐
总的来说,Java+Hibernate双数据源配置是一项关键技能,它使得开发者能够在同一个应用中管理和操作多个数据库,实现读写分离、负载均衡等高级功能。结合SpringBoot的自动化配置和AOP特性,能够简化配置过程,提升...
在上面的配置中,我们使用 DynamicDataSource 作为 Hibernate 的数据源, Hibernate 将根据当前的数据库连接信息选择对应的数据源。 使用 Spring 框架和 Hibernate,我们可以轻松地配置多数据库连接信息,并自由...
在多数据源环境下,可以通过SessionFactory和Session接口配置多个数据源,每个数据源对应一个SessionFactory,以处理不同数据库的连接。 Maven是项目管理工具,它帮助开发者管理项目的构建、依赖和生命周期。在多库...
- **数据源配置**:在应用服务器(如Tomcat)或应用代码中配置数据源,以便于Hibernate使用。 - **SessionFactory的缓存策略**:可以设置一级缓存和二级缓存,优化性能。 - **错误处理和异常处理**:在获取Session或...
配置Hibernate数据源是一项基础而重要的任务,涉及在Java应用程序中集成和使用Hibernate框架以及MySQL数据库。以下内容旨在详细介绍如何在MyEclipse开发环境中配置Hibernate数据源,同时解释相关概念和步骤。 首先...
- **Hibernate Session**:在 Hibernate 中,Session 是数据源与实体对象之间的桥梁,用于执行 CRUD 操作。 - **SessionFactory**:SessionFactory 是一个线程安全的工厂对象,用于创建 Session,通常在应用程序启动...
本文将详细介绍在Hibernate框架中配置不同数据源的方法,帮助读者更好地理解和应用这些配置。 #### 二、数据源的重要性 数据源是应用程序与数据库之间建立连接的重要桥梁。通过合理的数据源配置,可以有效提升...
在多数据源环境中,Hibernate可以通过SessionFactory配置多个数据源,每个数据源对应一个SessionFactory。 3. **Atomikos**: Atomikos是一个开源的JTA(Java Transaction API)实现,提供分布式事务管理服务。在...
Hibernate配置各种数据源 <hibernate-configuration> <session-factory> <!– 各属性的配置–> <!—为true表示将Hibernate发送给数据库的sql显示出来 –> ”show_sql”>true <!– SQL方言,这边设定的是MySQL ...
总之,配置Hibernate数据源连接涉及多个层面,包括Hibernate配置文件、应用服务器的配置以及代码中的SessionFactory初始化。正确配置这些元素,能够确保应用程序顺利地通过Hibernate与数据库交互,实现高效、稳定的...
SSH动态切换数据源是一种在Java Web开发中处理多数据库连接切换的技术,主要应用于Spring、Struts和Hibernate(SSH)这三大框架集成的项目。SSH框架是企业级应用开发的常用组合,提供了强大的业务逻辑处理和数据持久...
这个过程包括定义和配置多个DataSource bean,调整Hibernate和Struts2的配置以适应不同的数据源,以及在业务逻辑中适当地切换和使用这些数据源。正确配置后,SSH框架能够灵活地处理多数据库环境,提高应用的可扩展性...
这份源代码集可以帮助开发者深入学习Hibernate的核心功能和最佳实践,包括对象关系映射(ORM)、查询语言(HQL)、事务管理以及缓存策略等多个方面。 1. Hibernate简介:Hibernate是Java领域中最流行的ORM框架之一...
标题“多数据源---SessionFactory”表明我们将讨论的是如何在Hibernate框架下,实现对多个数据库进行操作的机制。Hibernate是一个强大的Java持久层框架,它的SessionFactory是其核心组件之一,负责管理与数据库的...
1. SessionFactory:它是Hibernate的主要工厂类,负责配置、加载和管理所有持久化类的元数据,创建Session实例。 2. Session:是与数据库交互的接口,负责保存、更新和删除实体对象,以及执行HQL和SQL查询。 3. ...
这通常涉及到数据源配置、Hibernate的属性设置等。 3. 整合Spring的DAO层:Spring通过声明式事务管理简化了事务处理。我们可以定义一个接口,如`UserDao`,包含增删改查等通用方法,然后使用Spring的`@Repository`...
通过`Session.createSQLQuery()`方法创建SQL查询,然后设置参数并获取结果集。例如: ```java String sql = "SELECT * FROM User WHERE id = ?"; SQLQuery query = session.createSQLQuery(sql); query....
Hibernate是一个开放源代码的对象关系映射(ORM)框架,它为开发者提供了在Java应用中操作数据库的强大工具。通过ORM,开发者可以使用面向对象的方式来处理数据,而无需直接编写SQL语句。这大大提高了开发效率并降低...
Spring 可以通过工厂方法或 JdbcTemplate、HibernateTemplate 提供的模板方法来获取 Session。 6. **Service 层设计**:Service 层是业务逻辑的核心,通常会注入 DAO 实例并调用其方法来完成业务处理。Service 层...
- **Session**: Session 是与数据库进行交互的接口,它管理对象的状态,提供了保存、更新、删除对象以及查询数据的方法。 2. **对象状态(Object State)** - **持久态(Persistent)**: 当对象与 Session 关联并...