hibernate动态切换数据源
起因:
公司的当前产品,主要是两个项目集成的,一个是java项目,还有一个是php项目,两个项目用的是不同的数据源,但都是mysql数据库,因为java这边的开发工作已经基本完成了,而php那边任务还很多,人手也比较紧,产品上线日期紧促,所以领导希望java这边能够帮助php那边写接口,所以需要切换数据源
思路:
困难解决:
1、配置dataSource的时候将id写成那么,而动态数据源的设置引用的是id
2、动态数据源的切换不能用枚举来标识,得用常量
3、在mysql数据库中不同种类的table也照样起作用
4、spring的事务处理可能会影响动态数据源的切换(尚未发现该问题)
测试环境:
1、hibernate
2、spring
3、mysql
最终实现:
1、首先得配置多个数据源
<!-- 配置数据源 使用的是Druid数据源 -->
<bean id="dataSource1" class="com.alibaba.druid.pool.DruidDataSource"
init-method="init" destroy-method="close">
<property name="url" value="${jdbc.url1}" />
<property name="username" value="${jdbc.username1}" />
<property name="password" value="${jdbc.password1}" /> <!-- 初始化连接大小 -->
<property name="initialSize" value="0" />
<!-- 连接池最大使用连接数量 -->
<property name="maxActive" value="20" /> <!-- 连接池最小空闲 -->
<property name="minIdle" value="0" />
<!-- 获取连接最大等待时间 -->
<property name="maxWait" value="60000" />
<property name="poolPreparedStatements" value="true" />
<property name="maxPoolPreparedStatementPerConnectionSize"
value="33" />
<!-- 用来检测有效sql -->
<property name="validationQuery" value="${validationQuery}" />
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" />
<property name="testWhileIdle" value="true" />
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="60000" />
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="25200000" />
<!-- 打开removeAbandoned功能 -->
<property name="removeAbandoned" value="true" />
<!-- 1800秒,也就是30分钟 -->
<property name="removeAbandonedTimeout" value="1800" />
<!-- 关闭abanded连接时输出错误日志 -->
<property name="logAbandoned" value="true" />
<!-- 监控数据库 -->
<property name="filters" value="mergeStat" />
</bean> <!-- 配置数据源 使用的是Druid数据源 -->
<bean id="dataSource2" class="com.alibaba.druid.pool.DruidDataSource"
init-method="init" destroy-method="close">
<property name="url" value="${jdbc.url2}" />
<property name="username" value="${jdbc.username2}" />
<property name="password" value="${jdbc.password2}" /> <!-- 初始化连接大小 -->
<property name="initialSize" value="0" />
<!-- 连接池最大使用连接数量 -->
<property name="maxActive" value="20" /> <!-- 连接池最小空闲 -->
<property name="minIdle" value="0" />
<!-- 获取连接最大等待时间 -->
<property name="maxWait" value="60000" />
<property name="poolPreparedStatements" value="true" />
<property name="maxPoolPreparedStatementPerConnectionSize"
value="33" />
<!-- 用来检测有效sql -->
<property name="validationQuery" value="${validationQuery}" />
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" />
<property name="testWhileIdle" value="true" />
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="60000" />
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="25200000" />
<!-- 打开removeAbandoned功能 -->
<property name="removeAbandoned" value="true" />
<!-- 1800秒,也就是30分钟 -->
<property name="removeAbandonedTimeout" value="1800" />
<!-- 关闭abanded连接时输出错误日志 -->
<property name="logAbandoned" value="true" />
<!-- 监控数据库 -->
<property name="filters" value="mergeStat" />
</bean>
然后配置多数据源映射关系
<!-- 编写spring 配置文件的配置多数源映射关系 -->
<bean id="dataSource" class="com.asen.util.DynamicDataSource">
<property name="targetDataSources">
<map key-type="java.lang.String">
<entry key="CCVZB" value-ref="dataSource1"></entry>
<entry key="CCSC" value-ref="dataSource2"></entry>
</map>
</property>
<property name="defaultTargetDataSource" ref="dataSource1"></property>
</bean>
然后是hibernate的SessionFactory
<!-- 配置hibernate的SessionFactory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<!-- 注入数据源 相关信息看源码 -->
<property name="dataSource" ref="dataSource" />
<!-- hibernate配置信息 -->
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
</props>
</property>
<!-- 扫描hibernate注解配置的entity -->
<property name="packagesToScan" value="com.asen.app.*" />
</bean>
这样配置文件就写好了,但是还需要三个类
package com.asen.util; import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DynamicDataSourceHolder.getDataSourceType();
} }
package com.asen.util; public class DynamicDataSourceGlobal {
public static final String CCVZB="CCVZB";
public static final String CCSC="CCSC";
}
package com.asen.util; public class DynamicDataSourceHolder {
// 线程本地环境
private static final ThreadLocal contextHolder = new ThreadLocal(); // 设置数据源类型
public static void setDataSourceType(String dataSourceType) {
contextHolder.set(dataSourceType);
} // 获取数据源类型
public static String getDataSourceType() {
return (String) contextHolder.get();
} // 清除数据源类型
public static void clearDataSourceType() {
contextHolder.remove();
} }
具体切换
package com.asen.app.dao.impl; import java.util.List; import javax.annotation.Resource; import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.stereotype.Repository; import com.asen.app.dao.IHomeFunctionDao;
import com.asen.util.DynamicDataSourceGlobal;
import com.asen.util.DynamicDataSourceHolder; @Repository("homeFunctionDao")
public class HomeFunctionDaoImpl extends HibernateDaoSupport implements IHomeFunctionDao { @Resource
public void setSessionFacotry(SessionFactory sessionFacotry) {
super.setSessionFactory(sessionFacotry);
} @Override
public List getHomeFunctionList() throws Exception {
DynamicDataSourceHolder.setDataSourceType(DynamicDataSourceGlobal.CCVZB);
SessionFactory sessionFactory = getHibernateTemplate().getSessionFactory();
Session session = sessionFactory.openSession();
Query query = session.createQuery("from HomeFunction");
return query.list();
}
}
hibernate动态切换数据源的更多相关文章
- Spring3.3 整合 Hibernate3、MyBatis3.2 配置多数据源/动态切换数据源 方法
一.开篇 这里整合分别采用了Hibernate和MyBatis两大持久层框架,Hibernate主要完成增删改功能和一些单一的对象查询功能,MyBatis主要负责查询功能.所以在出来数据库方言的时候基 ...
- Spring3.3 整合 Hibernate3、MyBatis3.2 配置多数据源/动态切换数据源方法
一.开篇 这里整合分别采用了Hibernate和MyBatis两大持久层框架,Hibernate主要完成增删改功能和一些单一的对象查询功能,MyBatis主要负责查询功能.所以在出来数据库方言的时候基 ...
- Spring + Mybatis 项目实现动态切换数据源
项目背景:项目开发中数据库使用了读写分离,所有查询语句走从库,除此之外走主库. 最简单的办法其实就是建两个包,把之前数据源那一套配置copy一份,指向另外的包,但是这样扩展很有限,所有采用下面的办法. ...
- 在使用 Spring Boot 和 MyBatis 动态切换数据源时遇到的问题以及解决方法
相关项目地址:https://github.com/helloworlde/SpringBoot-DynamicDataSource 1. org.apache.ibatis.binding.Bind ...
- Spring学习总结(16)——Spring AOP实现执行数据库操作前根据业务来动态切换数据源
深刻讨论为什么要读写分离? 为了服务器承载更多的用户?提升了网站的响应速度?分摊数据库服务器的压力?就是为了双机热备又不想浪费备份服务器?上面这些回答,我认为都不是错误的,但也都不是完全正确的.「读写 ...
- Spring+Mybatis动态切换数据源
功能需求是公司要做一个大的运营平台: 1.运营平台有自身的数据库,维护用户.角色.菜单.部分以及权限等基本功能. 2.运营平台还需要提供其他不同服务(服务A,服务B)的后台运营,服务A.服务B的数据库 ...
- 基于AbstractRoutingDataSource实现动态切换数据源
基于AbstractRoutingDataSource实现动态切换数据源 /** * DataSource注解接口 */ @Target({ElementType.TYPE, ElementTyp ...
- Spring动态切换数据源及事务
前段时间花了几天来解决公司框架ssm上事务问题.如果不动态切换数据源话,直接使用spring的事务配置,是完全没有问题的.由于框架用于各个项目的快速搭建,少去配置各个数据源配置xml文件等.采用了动态 ...
- AOP获取方法注解实现动态切换数据源
AOP获取方法注解实现动态切换数据源(以下方式尚未经过测试,仅提供思路) ------ 自定义一个用于切换数据源的注解: package com.xxx.annotation; import org. ...
随机推荐
- [题解]bzoj 1861 Book 书架 - Splay
1861: [Zjoi2006]Book 书架 Time Limit: 4 Sec Memory Limit: 64 MBSubmit: 1396 Solved: 803[Submit][Stat ...
- 如何设置打开jsp页面速度加快?
1.
- "SQLServer复制需要有实际的服务器名称才能连接到服务器,请指定实际的服务器名"转
"SQLServer复制需要有实际的服务器名称才能连接到服务器,请指定实际的服务器名" 2014-06-12 12:01:10 最近在学习SQL SERVER的高级复制技术的时候 ...
- java_web学习(16)Ajax
Ajax Ajax(Asynchronous JavaScript and XML的缩写),允许浏览器与服务器通信而无须刷新当前页面的技术都被叫做Ajax. Ajax:一种不用 ...
- Linux笔记(十三) - 系统管理
(1)进程管理1.判断服务器健康状态2.查看进程a.查看系统中所有进程:ps 例:ps aux(使用BSD操作系统命令格式) a 显示所有前台进程 x 显示所有后台进程 u 显 ...
- 我的2016年终总结(PF项目框架设计心得分享 2.0rc)
在无数的日夜里,熬出了多少的黑眼圈,致勤勤恳恳工作的各位朋友与自己.每到了年末的时候总想写的什么,主要是为了回顾以往一年里到底做了什么,这便是年终总结的主要意义.在此我将要总结的是和我在技术层面上成长 ...
- ADO.NET高级应用
ADO.NET事务处理(4个步骤) 1.调用SqlConnection对象的BeginTransaction()方法,创建一个SqlTransaction对象,标志事务开始. 2.将创建的SqlTra ...
- [CSS3] 学习笔记-背景与边框相关样式
1.与背景相关的新增属性 包括:backgroud-clip,backgroud-origin,backgroud-size <!DOCTYPE html> <html> &l ...
- input _文本框回车或者失去光标触发事件
IE下,当一个HTML元素的属性改变的时候,都能通过 onpropertychange来即时捕获. onchange在属性值改变时还必须使得当前元素失去焦点(onblur)才可以激活该事件. 了解这一 ...
- form表单的两种提交方式,submit和button的用法
1.当输入用户名和密码为空的时候,需要判断.这时候就用到了校验用户名和密码,这个需要在jsp的前端页面写:有两种方法,一种是用submit提交.一种是用button提交.方法一: 在jsp的前端页面的 ...