Spring+Hibernate实现动态SessionFactory切换
场景:
1)系统有多个数据库
2)且数据库类型也不尽相同
3)现在应用根据某些条件路由到具体的数据库
4)且在spring+hibernate框架下,支持依赖注入
已有实现,spring动态数据源,但无法实现动态SessionFactory,即不通数据库的方言不一样
目标:
在spring动态数据源的基础上,实现动态SessionFactory
1.配置多个数据源和SessionFactory,并给相应SessionFactory配置事务管理:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<!-- FOR SqlServer-->
<bean id="SqlServer_DataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver" />
<property name="url"
value="url" />
<property name="username" value="username" />
<property name="password" value="password" />
</bean>
<bean id="SqlServer_SessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"
p:mappingLocations="classpath:/com/entity/*.hbm.xml">
<property name="dataSource" ref="SqlServer_DataSource" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.query.factory_class">org.hibernate.hql.ast.ASTQueryTranslatorFactory</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.SQLServer2008Dialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
</props>
</property>
</bean>
<bean id="SqlServer_TransactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="SqlServer_SessionFactory"/>
</bean> <!-- FOR Oracle -->
<bean id="Oracle _DataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="oracle.jdbc.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:@localhost:1521/orcl" />
<property name="username" value="username" />
<property name="password" value="password" />
</bean>
<bean id="Oracle_SessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"
p:mappingLocations="classpath:/com/entity/*.hbm.xml">
<property name="dataSource" ref="Oracle_DataSource" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.query.factory_class">org.hibernate.hql.ast.ASTQueryTranslatorFactory</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
</props>
</property>
</bean>
<bean id="Oracle_TransactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="Oracle_SessionFactory"/>
</bean> </beans>
2. 为SessionFactory配置事务切面:
<tx:advice id="SqlServer_TxAdvice" transaction-manager="SqlServer_TransactionManager">
<tx:attributes>
<tx:method name="get*" read-only="true" />
<tx:method name="find*" read-only="true" />
<tx:method name="*" propagation="REQUIRED" rollback-for="Exception" />
</tx:attributes>
</tx:advice>
<tx:advice id="Oracle_TxAdvice" transaction-manager="Oracle_TransactionManager">
<tx:attributes>
<tx:method name="get*" read-only="true" />
<tx:method name="find*" read-only="true" />
<tx:method name="*" propagation="REQUIRED" rollback-for="Exception" />
</tx:attributes>
</tx:advice> <aop:config proxy-target-class="true">
<aop:pointcut id="txPointcut" expression="execution(* com.service.*.*(..))"/>
<aop:advisor advice-ref="SqlServer_TxAdvice" pointcut-ref="txPointcut" order="1"/>
<aop:advisor advice-ref="Oracle_TxAdvice" pointcut-ref="txPointcut" order="2"/>
</aop:config>
3. 配置一个动态的SessionFactory:
<bean id="sessionFactory" class="com.DynamicSessionFactory"/>
4. 定义DynamicSessionFactory实现接口SessionFactory:
public class DynamicSessionFactory implements SessionFactory ,ApplicationContextAware{
private static final long serialVersionUID = 1L;
private ApplicationContext applicationContext;
private SessionFactory getSessionFactory(String name) {
return (SessionFactory) applicationContext.getBean(name);
}
//根据当前线程的SessionFactoryName获取SessionFactory
private SessionFactory getSessionFactory() {
return getSessionFactory(ThreadLocalUtil.
.getSessionFactoryName());
}
public Reference getReference() throws NamingException {
return getSessionFactory().getReference();
}
public Session openSession() throws HibernateException {
return getSessionFactory().openSession();
}
public Session openSession(Interceptor interceptor)
throws HibernateException {
return getSessionFactory().openSession(interceptor);
}
public Session openSession(Connection connection) {
return getSessionFactory().openSession(connection);
}
public Session openSession(Connection connection, Interceptor interceptor) {
return getSessionFactory().openSession(connection,interceptor);
}
public Session getCurrentSession() throws HibernateException {
return getSessionFactory().getCurrentSession();
}
public StatelessSession openStatelessSession() {
return getSessionFactory().openStatelessSession();
}
public StatelessSession openStatelessSession(Connection connection) {
return getSessionFactory().openStatelessSession(connection);
}
public ClassMetadata getClassMetadata(Class entityClass) {
return getSessionFactory().getClassMetadata(entityClass);
}
public ClassMetadata getClassMetadata(String entityName) {
return getSessionFactory().getClassMetadata(entityName);
}
public CollectionMetadata getCollectionMetadata(String roleName) {
return getSessionFactory().getCollectionMetadata(roleName);
}
public Map getAllClassMetadata() {
return getSessionFactory().getAllClassMetadata();
}
public Map getAllCollectionMetadata() {
return getSessionFactory().getAllCollectionMetadata();
}
public Statistics getStatistics() {
return getSessionFactory().getStatistics();
}
public void close() throws HibernateException {
getSessionFactory().close();
}
public boolean isClosed() {
return getSessionFactory().isClosed();
}
public Cache getCache() {
return getSessionFactory().getCache();
}
public void evict(Class persistentClass) throws HibernateException {
getSessionFactory().evict(persistentClass);
}
public void evict(Class persistentClass, Serializable id)
throws HibernateException {
getSessionFactory().evict(persistentClass, id);
}
public void evictEntity(String entityName) throws HibernateException {
getSessionFactory().evictEntity(entityName);
}
public void evictEntity(String entityName, Serializable id)
throws HibernateException {
getSessionFactory().evictEntity(entityName, id);
}
public void evictCollection(String roleName) throws HibernateException {
getSessionFactory().evictCollection(roleName);
}
public void evictCollection(String roleName, Serializable id)
throws HibernateException {
getSessionFactory().evictCollection(roleName, id);
}
public void evictQueries(String cacheRegion) throws HibernateException {
getSessionFactory().evictQueries(cacheRegion);
}
public void evictQueries() throws HibernateException {
getSessionFactory().evictQueries();
}
public Set getDefinedFilterNames() {
return getSessionFactory().getDefinedFilterNames();
}
public FilterDefinition getFilterDefinition(String filterName)
throws HibernateException {
return getSessionFactory().getFilterDefinition(filterName);
}
public boolean containsFetchProfileDefinition(String name) {
return getSessionFactory().containsFetchProfileDefinition(name);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
this.applicationContext = applicationContext;
}
}
Spring+Hibernate实现动态SessionFactory切换的更多相关文章
- Spring+Hibernate实现动态SessionFactory切换(改进版)
前面写了一篇关于动态切换Hibernate SessionFactory的文章 发现存在一些问题: 需要配置多个HibernateTransactionManager和多个Spring 切面 这样带来 ...
- Spring(AbstractRoutingDataSource)实现动态数据源切换--转载
原始出处:http://linhongyu.blog.51cto.com/6373370/1615895 一.前言 近期一项目A需实现数据同步到另一项目B数据库中,在不改变B项目的情况下,只好选择项目 ...
- Spring(AbstractRoutingDataSource)实现动态数据源切换
转自: http://blog.51cto.com/linhongyu/1615895 一.前言 近期一项目A需实现数据同步到另一项目B数据库中,在不改变B项目的情况下,只好选择项目A中切换数据源,直 ...
- spring hibernate实现动态替换表名(分表)
1.概述 其实最简单的办法就是使用原生sql,如 session.createSQLQuery("sql"),或者使用jdbcTemplate.但是项目中已经使用了hql的方式查询 ...
- dubbo服务+Spring事务+AOP动态数据源切换 出错
1:问题描述,以及分析 项目用了spring数据源动态切换,服务用的是dubbo.在运行一段时间后程序异常,更新操作没有切换到主库上. 这个问题在先调用读操作后再调用写操作会出现. 经日志分析原因: ...
- spring AbstractRoutingDataSource实现动态数据源切换
使用Spring 提供的 AbstractRoutingDataSource 实现 创建 AbstractRoutingDataSource 实现类,负责保存所有数据源与切换数据源策略:public ...
- Spring 实现动态数据源切换--转载 (AbstractRoutingDataSource)的使用
[参考]Spring(AbstractRoutingDataSource)实现动态数据源切换--转载 [参考] 利用Spring的AbstractRoutingDataSource解决多数据源的问题 ...
- 30个类手写Spring核心原理之动态数据源切换(8)
本文节选自<Spring 5核心原理> 阅读本文之前,请先阅读以下内容: 30个类手写Spring核心原理之自定义ORM(上)(6) 30个类手写Spring核心原理之自定义ORM(下)( ...
- Spring整合Hibernate 一 - 注入SessionFactory
Spring3 整合 Hibernate4 - 注入SessionFactory 版本: spring-framework-3.2.4.RELEASE hibernate-release-4.2.5. ...
随机推荐
- mysql 中文乱码 解决
数据库安装设置编码: mysql默认的字符编码是latin1,而我用的是utf-8,存入数据库就变成了?????这样的乱码,解决方法: 修改安装路径下的my.ini文件,default-chara ...
- 使用ms owin 搭建oauth2 server
http://www.asp.net/aspnet/overview/owin-and-katana/owin-oauth-20-authorization-server 有示例代码 关于token的 ...
- C# 委托、匿名方法、扩展方法
一.委托的使用: 详细委托和事件解释请看另一篇:http://www.cnblogs.com/Liyuting/p/6760706.html 二.匿名方法 三.扩展方法
- async 和 await 的用法示例
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- 商城项目,java返回json数据,报错406
前言: 项目结构为maven,搭建好架构,整合ssm,进行测试, 从数据库中查询数据,返回json数据,结果报错406 问题: 解决: 1,确定项目中json包是否存在(极大可能出于此) 2,处理器适 ...
- springboot +element-axios跨域请求
1.初始化element项目 1.1:vue init webpage '项目名称' 1.2:npm i element-ui -S 1.3:在main.js添加 import ElementUI f ...
- nginx 错误日志分析
502 1.查看nginx错误日志 tailf /data/log/nginx/error.log // :: [error] #: * recv() failed (: Connection res ...
- java设计模式-----10、享元模式
Flyweight模式也叫享元模式,是构造型模式之一,它通过与其他类似对象共享数据来减小内存占用.它使用共享物件,用来尽可能减少内存使用量以及分享资讯给尽可能多的相似物件:它适合用于只是因重复而导致使 ...
- 纪念Vamai
知道Vamei这位博主去世的消息有些日子啦,在他的豆瓣主页也留下了只言片语,他写的协议森林让我印象深刻,在博客园也是我关注列表里的一位. 本来没打算写一篇文来说Vamei去世的事情,不过意外之是加 ...
- c#如何禁用win7的任务管理器
以前制作的桌面锁屏软件虽然也禁用过任务管理器,但是采取的是比较笨的方法,而且对操作系统还有一定的危害.因为任务管理也是一个窗体也就是说它中也是一个独立进程,所以只需要强制性关闭这个进程即可以关闭任务管 ...