spring下动态数据源的切换

来源:互联网 发布:人工智能 学问 编辑:程序博客网 时间:2024/05/16 09:02

由于项目需求,做了一个给予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时,自动切换至默认数据源 */@Overrideprotected 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();}}

spring 配置:

<!--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);数据源就自动切换成你想要使用的那个了

原创粉丝点击