最近遇到这样的一个场景:
1、 先查询oralce 一个表空间的中一个表的数据、作为定时器启动
2、也需要查询oracle另一个表空间的一个表的数据,作为显示数据。
问题点:这两个表空间又没有互相访问的权限。
为了解决这个问题:采用嗯动态切换数据源
按我理解的思路配置:
1、在spring 配置文件配置、数据源1、数据源2
2、在spring 配置文件中 通过一个动态类 把这两个数据源映射,并配置一个默认的数据源
3、把这个动态数据类 映射给hibernate sessionFactory session工厂
1、spring 配置文件中 配置两个数据源、分别是dataSource1和 dataSource2
两个数据源分别配置两个库用户名和密码
<bean name="dataSource1" class="com.alibaba.druid.pool.DruidDataSource"
init-method="init" destroy-method="close">
<property name="url" value="${jdbcUrl}" />
<property name="username" value="${username1}" />
<property name="password" value="${password1}" />
<!-- 初始化连接大小 -->
<property name="initialSize" value="0" />
<!-- 连接池最大使用连接数量 -->
<property name="maxActive" value="20" />
<!-- 连接池最大空闲 -->
<!-- <property name="maxIdle" value="20" /> -->
<!-- 连接池最小空闲 -->
<property name="minIdle" value="0" />
<!-- 获取连接最大等待时间 -->
<property name="maxWait" value="60000" />
<property name="validationQuery" value="true" />
<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="stat" /> -->
<property name="filters" value="mergeStat" />
</bean>
<!-- 配置数据源2 -->
<bean name="dataSource2" class="com.alibaba.druid.pool.DruidDataSource"
init-method="init" destroy-method="close">
<property name="url" value="${jdbcUrl}" />
<property name="username" value="${username2}" />
<property name="password" value="${password2}" />
<!-- 初始化连接大小 -->
<property name="initialSize" value="0" />
<!-- 连接池最大使用连接数量 -->
<property name="maxActive" value="20" />
<!-- 连接池最大空闲 -->
<!-- <property name="maxIdle" value="20" /> -->
<!-- 连接池最小空闲 -->
<property name="minIdle" value="0" />
<!-- 获取连接最大等待时间 -->
<property name="maxWait" value="60000" />
<property name="validationQuery" value="true" />
<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="stat" /> -->
<property name="filters" value="mergeStat" />
</bean>
2、 编写spring 配置文件的配置多数源映射关系 -
<bean id="dynamicDataSource" class="com.xxx.core.dataSource.DynamicDataSource" >
<property name="targetDataSources">
<map key-type="java.lang.String">
<entry value-ref="dataSource1" key="dataSource1"></entry>
<entry value-ref="dataSource2" key="dataSource2"></entry>
</map>
</property>
<property name="defaultTargetDataSource" ref="dataSource1">
</property>
</bean>
<!-- 配置到hibernate session工厂 -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dynamicDataSource" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="current_session_context_class">org.springframework.orm.hibernate4.SpringSessionContext
</prop>
</props>
</property>
<!-- 自动扫描hbm方式配置的hibernate文件和.hbm文件 -->
<property name="mappingLocations">
<list>
<value>classpath*:com/xxx/model/*.hbm.xml</value>
</list>
</property>
</bean>
3、自己创建DynamicDataSource
com.xxx.core.dataSource.DynamicDataSource 这个类
DynamicDataSource继承AbstractRoutingDataSource类,并实现了determineCurrentLookupKey()方法。该方法可以实现数据库的动态切换
public class DynamicDataSource extends AbstractRoutingDataSource{
@Override
protected Object determineCurrentLookupKey() {
return DataSourceContextHolder.getDataSourceType();//DataSourceContextHolder也需要创建
}
}
4、自己创建当前线程的变量的工具类DataSourceContextHolder ,用于设置对应的数据源名称:
public class DataSourceContextHolder {
private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();
/**
* @Description: 设置数据源类型
* @param dataSourceType 数据库类型
* @return void
* @throws
*/
public static void setDataSourceType(String dataSourceType) {
contextHolder.set(dataSourceType);
}
/**
* @Description: 获取数据源类型
* @param
* @return String
* @throws
*/
public static String getDataSourceType() {
return contextHolder.get();
}
/**
* @Description: 清除数据源类型
* @param
* @return void
* @throws
*/
public static void clearDataSourceType() {
contextHolder.remove();
}
}
以上就完成配置了
5、写个测试方法 看是否生效(思路就是思路就是 切换之后,看是否有对应的表能查出数据
DataSourceContextHolder.setDataSourceType(“dataSource1”);
就可以进行切换数据源,看是否能查出对应数据库表中的数据。
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext(new String[] { "classpath:applicationContext.xml"});
//指定数据源
DataSourceContextHolder.setDataSourceType("dataSource1");
BaseDao baseDao = (BaseDao)ac.getBean("baseDao");
List list = baseDao.findBySql("select * from table1");
for(int i=0;i<list.size();i++){
System.out.println(list.get(i));
}
DataSourceContextHolder.setDataSourceType("dataSource2");
List list2 =baseDao.findBySql(" select * from table2 t");
for(int i=0;i<list2.size();i++){
System.out.println(list2.get(i));
}
}
如果没有数据库的事务管理,已经可以实现数据库的动态切换了。但是如果涉及到数据库的事务管理,需要在数据库事务开启切换数据库,
否则数据库的切换只能在下次数据库操作时才生效
https://www.cnblogs.com/softidea/p/7127874.html?utm_source=itdadao&utm_medium=referral
http://blog.youkuaiyun.com/u011463444/article/details/72842500
http://blog.youkuaiyun.com/gaofuqi/article/details/46417281
---------------------
原文:https://blog.youkuaiyun.com/u010050174/article/details/79307690
版权声明:本文为博主原创文章,转载请附上博文链接!