Spring项目配置多数据源

项目中有用到多数据源,并进行动态切换,使用的是阿里的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 

原文地址:https://www.cnblogs.com/commissar-Xia/p/11182139.html