项目中有用到多数据源,并进行动态切换,使用的是阿里的druid。看网上有一篇大致一样的就偷偷懒

import java.sql.SQLFeatureNotSupportedException;
import java.util.Map;
import com.alibaba.druid.pool.DruidDataSource;
import org.apache.log4j.Logger;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; import com.xyh.util.SpringUtils; /**
* @author yuanhao
* @describe 实现动态数据源切换逻辑
*/
public class DataSourceUtil extends AbstractRoutingDataSource {
private Logger log = Logger.getLogger(this.getClass());
/**
* 数据源资源池
*/
private Map<Object, Object> _targetDataSources;
/**
* 数据源名称
*/ /**
* @see org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource#determineCurrentLookupKey()
* @describe 数据源为空或者为0时,自动切换至默认数据源
*/
@Override
protected Object determineCurrentLookupKey() {
String dataSourceName = DBContextHolder.getDataSource();
try { if (dataSourceName == null || "".equals(dataSourceName)) {// 如果传入数据源id为空
throw new Exception("传入的数据源名称为空,无法选择数据源");
}
this.selectDataSource(dataSourceName);
} catch (Exception e) {
e.printStackTrace();
}
log.debug("--------> use datasource " + dataSourceName);
return dataSourceName;
}
/**
* @param key
* 数据源id
* @throws Exception
* @describe 数据源存在连接池中时不做处理, 不存在将新数据链接添加至连接池
* /
public void selectDataSource(String dataSourceName) throws Exception { Object obj = this._targetDataSources.get(dataSourceName);
// 如果数据源已经有了
if (obj != null) {
return;
} else {// 如果没有则从spring容器中获取
DruidDataSource dataSource = (DruidDataSource) SpringUtils
.getBeanInstance(dataSourceName);
if (dataSource != null)
this.setDataSource(dataSourceName, dataSource);
else {
throw new Exception("无法取得数据库连接配置,请核对是否已经配置");
}
} } /**
* 将数据源写入池中
* @param key
* @param dataSource
*/
private void setDataSource(String dataSourceName, DruidDataSource dataSource) {
//this.addTargetDataSource(dataSourceName, dataSource);
this._targetDataSources.put(dataSourceName, dataSource);
this.setTargetDataSources(this._targetDataSources);
} @SuppressWarnings({ "unchecked", "rawtypes" })
public void setTargetDataSources(Map targetDataSources) {
this._targetDataSources = targetDataSources;
super.setTargetDataSources(this._targetDataSources);
afterPropertiesSet();
}
/*
public void addTargetDataSource(String key, DruidDataSource dataSource) { }*/
/**
* @return
* @throws SQLFeatureNotSupportedException
*/ public java.util.logging.Logger getParentLogger()
throws SQLFeatureNotSupportedException {
// TODO Auto-generated method stub
return null;
}
}

数据源选择工具类

public class DBContextHolder {
private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();
/**
* 传入数据源名称
*
* @param key
*/
public static void setDataSource(String key) {
contextHolder.set(key);
} /**
* 取数据源名称
*
* @return
*/
public static String getDataSource() {
return contextHolder.get();
} /**
* 销毁数据源名称
*
* @return
*/
public static void clearDataSource() {
contextHolder.remove();
}
}

pring 配置:

<!--db1-->
<bean id="dataSource411602" class="com.alibaba.druid.pool.DruidDataSource"
destroy-method="close" lazy-init="true">
<property name="driverClassName">
<value>${jdbc.oracle.driverClassName}</value>
</property>
<property name="url">
<value>jdbc:oracle:thin:@192.168.0.1:20003:orcl</value>
</property>
<property name="username">
<value>test</value>
</property>
<property name="password">
<value>test</value>
</property>
<property name="filters" value="stat"></property>
</bean>
<!--db2-->
<bean id="dataSource411606" class="com.alibaba.druid.pool.DruidDataSource"
destroy-method="close" lazy-init="true">
<property name="driverClassName">
<value>${jdbc.oracle.driverClassName}</value>
</property>
<property name="url">
<value>jdbc:oracle:thin:@192.168.0.2:60021:orcl</value>
</property>
<property name="username">
<value>test</value>
</property>
<property name="password">
<value>test</value>
</property>
<property name="filters" value="stat"></property>
</bean>
<!--数据源-->
<bean id="dataSource" class="com.xyh.util.dbutil.DataSourceUtil">
<property name="targetDataSources">
<map key-type="java.lang.String">
</map>
</property>
</bean>
<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocations">
<list>
<value>classpath:sql-map-config.xml</value>
</list>
</property>
<property name="dataSource" ref="dataSource" />
</bean> <!-- JDBC 事务管理 -->
<bean id="jdbcTxManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource">
<ref bean="dataSource" />
</property>
</bean>

使用的时候只需要在要切换数据源的地方写下以下代码DBContextHolder.setDataSource(beanId);数据源就自动切换成你想要使用的那个了!!!

---------------------
原文:https://blog.csdn.net/qq_15541045/article/details/78736526

Spring项目配置多数据源的更多相关文章

  1. spring项目配置双数据源读写分离

    我们最早做新项目的时候一直想做数据库的读写分离与主从同步,由于一些原因一直没有去做这个事情,这次我们需要配置双数据源的起因是因为我们做了一个新项目用了另一个数据库,需要把这个数据库的数据显示到原来的后 ...

  2. Spring动态配置多数据源

    Spring动态配置多数据源,即在大型应用中对数据进行切分,并且采用多个数据库实例进行管理,这样可以有效提高系统的水平伸缩性.而这样的方案就会不同于常见的单一数据实例的方案,这就要程序在运行时根据当时 ...

  3. 如何通过Spring Boot配置动态数据源访问多个数据库

    之前写过一篇博客<Spring+Mybatis+Mysql搭建分布式数据库访问框架>描述如何通过Spring+Mybatis配置动态数据源访问多个数据库.但是之前的方案有一些限制(原博客中 ...

  4. spring+myBatis 配置多数据源,切换数据源

    注:本文来源于  tianzhiwuqis <spring+myBatis 配置多数据源,切换数据源> 一个项目里一般情况下只会使用到一个数据库,但有的需求是要显示其他数据库的内容,像这样 ...

  5. 一文读懂Spring动态配置多数据源---源码详细分析

    Spring动态多数据源源码分析及解读 一.为什么要研究Spring动态多数据源 ​ 期初,最开始的原因是:想将答题服务中发送主观题答题数据给批改中间件这块抽象出来, 但这块主要使用的是mq消息的方式 ...

  6. Spring Boot配置多数据源并实现Druid自动切换

    原文:https://blog.csdn.net/acquaintanceship/article/details/75350653 Spring Boot配置多数据源配置yml文件主数据源配置从数据 ...

  7. Spring+Hibernate配置多数据源

    配置说明 在实际应用中,经常会用到读写分离,这里就这种情况进行Spring+Hibernate的多数据源配置.此处的配置只是让读的方法操作一个数据库,写的方法操作另外一个数据库. 注:我这里的配置JD ...

  8. spring boot 配置双数据源mysql、sqlServer

    背景:原来一直都是使用mysql数据库,在application.properties 中配置数据库信息 spring.datasource.url=jdbc:mysql://xxxx/test sp ...

  9. spring中配置jdbc数据源

    1.加入jdbc驱动器包,mysql-connector-java.jar 2.加入commons-dbcp.jar配置数据源 3.在classpath下新建文件jdbc.properties,配置j ...

随机推荐

  1. 实战接口开发:python + flask + mysql + redis(根据反馈,持续细化更新。。。)

    前言 自动化已经成为测试的必备技能之一了,所以,很多想跳槽的测试朋友都在自学,特别是最实用的接口自动化, 但是很多人因为没有可以练手的项目而苦恼,最终导致缺乏实战经验,其实,完全可以自己开发个简单项目 ...

  2. Shiro密码加密

    Shiro密码加密 相关类 org.apache.shiro.authc.credential.CredentialsMatcher org.apache.shiro.authc.credential ...

  3. svn版本库操作(四)

    一.使用命令行模式访问 SVN 服务器 1. 检出(checkout) (1) 首先进入自己的工作目录,例如:D:\svnSpace cd D:\svnSpace (2) 运行 svn checkou ...

  4. ETA:

    Route-based models - Simple Additive Model- Data-driven Model Path-free models - MURAT Model Chun-Hs ...

  5. LG2272/BZOJ1093 「ZJOI2007」最大半连通子图 Tarjan缩点+DAG求最长链

    问题描述 LG2272 BZOJ1093 题解 观察半联通的定义,发现图中的一些结点,构成的链一定是一个半联通子图. 此时存在的环可能会干扰求解,于是\(\mathrm{Tarjan}\)缩点. 于是 ...

  6. odoo 新建模块命令

    python odoo-bin scaffold academy myaddons 自动初始化所有的配置信息: python odoo-bin --addons=addons,"/home/ ...

  7. GDB 调试C++

    原来比较熟悉用gdb调试C程序,没有用过gdb调试C++程序,原理上没有什么区别.在形式上有一些区别,因为C++支持名字空间和class等机制,把函数的可见域做了隔离. 拿envoy的代码作个例子: ...

  8. tornado中命名路由及反向解析使用

    一. 命名路由: 通常路由写法为[ (r'/' , Handler), ... ] 以上路由写法无法实现命名, 使用命名路由需借助tornado提供的方法, 如下: [ tornado.web.url ...

  9. [LeetCode] 454. 4Sum II 四数之和之二

    Given four lists A, B, C, D of integer values, compute how many tuples (i, j, k, l) there are such t ...

  10. Sentinel: 接入控制台实时查看监控数据

    Sentinel 提供一个轻量级的开源控制台,它提供机器发现以及健康情况管理.监控(单机和集群),规则管理和推送的功能. 比如我们之前是直接在代码中初始限流的值,接入控制台后可以直接通过控制台进行限流 ...