spring动态创建,加载,使用多数据源

spring动态创建,加载,使用多数据源

       在大物流可视化中,因为要源数据复杂,需要使用多个数据源。不是配置多个数据源,而是如何灵活动态的切换数据源。例如在ssm项目中,我们在spring配置中往往是配置一个datasource来连接数据库,然后绑定sessionFactory,在dao层代码中在指定sessionFactory来进行数据库操作


  正如上图所示,每一块都是绑定死的,如果是多个数据源,也只能是下图的方式。

       可以看出在Dao层代码中写死了两个sessionFactory,这样日后如果在多一个数据源,还要改代码添加一个SessionFactory,显然这并不符合开闭原则。
       那么正确的做法应该是

思路:
      配置 parentDataSource 的父bean.再配置多个数据源继承这个父bean,对driverClass,url,username,password,等数据源连接参数进行各自的重写。例如 mySqlDataSource ,在 DataSources bean中注入所有要切换的数据源,并且设置默认的数据源。


spring-mybatis.xml

<?xml version="1.0" encoding="UTF-8"?>  
<beans xmlns="http://www.springframework.org/schema/beans"  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"  
    xmlns:aop="http://www.springframework.org/schema/aop"  
    xsi:schemaLocation="  
        http://www.springframework.org/schema/beans   
        http://www.springframework.org/schema/beans/spring-beans-4.1.xsd   
        http://www.springframework.org/schema/tx   
        http://www.springframework.org/schema/tx/spring-tx-4.1.xsd  
        http://www.springframework.org/schema/aop   
        http://www.springframework.org/schema/aop/spring-aop-4.1.xsd  
        ">  
	  <!-- 数据源相同的内容 -->  
	<bean id="parentDataSource"  
	        class="org.apache.commons.dbcp.BasicDataSource" 
	        destroy-method="close">  
	        <!-- 连接池最大使用连接数 -->
		    <property name="maxActive">
		      <value>20</value>
		    </property>
		    <!-- 初始化连接大小 -->
		    <property name="initialSize">
		      <value>1</value>
		    </property>
		    <!-- 获取连接最大等待时间 -->
		    <property name="maxWait">
		      <value>60000</value>
		    </property>
		    <!-- 连接池最大空闲 -->
		    <property name="maxIdle">
		      <value>20</value>
		    </property>
		    <!-- 连接池最小空闲 -->
		    <property name="minIdle">
		      <value>3</value>
		    </property>
		    <!-- 自动清除无用连接 -->
		    <property name="removeAbandoned">
		      <value>true</value>
		    </property>
		    <!-- 清除无用连接的等待时间 -->
		    <property name="removeAbandonedTimeout">
		      <value>180</value>
		    </property>
		    <!-- 连接属性 -->
		    <property name="connectionProperties">
		      <value>clientEncoding=UTF-8</value>
		    </property>  
	</bean>  
	<!-- start以下配置各个数据源的特性 -->  
	<bean parent="parentDataSource" id="DvDataSource">
		<property name="driverClassName">
			<value>${jdbc_driverClassName}</value>
		</property>
		<property name="url">
		    <value>${dv_url}</value>
		</property>
		<property name="username">
		    <value>${jdbc_username}</value>
		</property>
		<property name="password">
		    <value>${jdbc_password}</value>
		</property>
	</bean> 
	<bean parent="parentDataSource" id="OcDataSource">   
	    <property name="driverClassName">
			<value>${jdbc_driverClassName}</value>
		</property>
		<property name="url">
		    <value>${oc_url}</value>
		</property>
		<property name="username">
		    <value>${jdbc_username}</value>
		</property>
		<property name="password">
		    <value>${jdbc_password}</value>
		</property>
	</bean> 
	<bean parent="parentDataSource" id="InDataSource">   
	    <property name="driverClassName">
			<value>${jdbc_driverClassName}</value>
		</property>
		<property name="url">
		    <value>${in_url}</value>
		</property>
		<property name="username">
		    <value>${jdbc_username}</value>
		</property>
		<property name="password">
		    <value>${jdbc_password}</value>
		</property>
	</bean>
	<bean parent="parentDataSource" id="WcDataSource">   
	    <property name="driverClassName">
			<value>${jdbc_driverClassName}</value>
		</property>
		<property name="url">
		    <value>${wc_url}</value>
		</property>
		<property name="username">
		    <value>${jdbc_username}</value>
		</property>
		<property name="password">
		    <value>${jdbc_password}</value>
		</property>
	</bean>
	<bean parent="parentDataSource" id="AcDataSource">   
	    <property name="driverClassName">
			<value>${jdbc_driverClassName}</value>
		</property>
		<property name="url">
		    <value>${ac_url}</value>
		</property>
		<property name="username">
		    <value>${jdbc_username}</value>
		</property>
		<property name="password">
		    <value>${jdbc_password}</value>
		</property>
	</bean>  
  
  <bean class="org.blue.ex.test.DynamicDataSource" id="dataSource">  
    <property name="targetDataSources">   
       <map key-type="java.lang.String"> 
       	   <entry value-ref="DvDataSource" key="DV"></entry>   
           <entry value-ref="OcDataSource" key="OC"></entry>  
           <entry value-ref="InDataSource" key="IN"></entry>
           <entry value-ref="WcDataSource" key="WC"></entry>
           <entry value-ref="AcDataSource" key="AC"></entry>
       </map>   
    </property>   
    <property name="defaultTargetDataSource" ref="DvDataSource" ></property>  
</bean>  
  
  
    <!-- myBatis文件 -->  
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">  
        <property name="dataSource" ref="dataSource" />  
        <!-- 自动扫描entity目录, 省掉Configuration.xml里的手工配置 -->  
        <property name="mapperLocations" value="classpath:mapper/*.xml" />  
    </bean>  
  
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">  
        <property name="basePackage" value="org.blue.ex.dao" />  
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />  
    </bean>  
  
    <!-- 配置事务管理器 -->  
    <bean id="transactionManager"  
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
        <property name="dataSource" ref="dataSource" />  
    </bean>  
  
    <!-- 注解方式配置事物 -->  
    <!-- <tx:annotation-driven transaction-manager="transactionManager" /> -->  
  
    <!-- 拦截器方式配置事物 -->  
    <tx:advice id="transactionAdvice" transaction-manager="transactionManager">  
        <tx:attributes>  
            <tx:method name="insert*" propagation="REQUIRED" />  
            <tx:method name="update*" propagation="REQUIRED" />  
            <tx:method name="delete*" propagation="REQUIRED" />  
  
            <tx:method name="get*" propagation="SUPPORTS" read-only="true" />  
            <tx:method name="find*" propagation="SUPPORTS" read-only="true" />  
            <tx:method name="select*" propagation="SUPPORTS" read-only="true" />  
  
        </tx:attributes>  
    </tx:advice>  
    <!-- Spring aop事务管理 -->  
    <aop:config>  
        <aop:pointcut id="transactionPointcut"  
            expression="execution(* org.blue.ex.service..*Impl.*(..))" />  
        <aop:advisor pointcut-ref="transactionPointcut"  
            advice-ref="transactionAdvice" />  
    </aop:config>  
  
</beans>  
DataSourceConst.java
package org.blue.ex.test;


/** 
 * 动态配置多数据源 
 * 数据源的名称常量类 
 * @author LONGHUI_LUO 
 * 
 */  
public class DataSourceConst { 
	/**
	 * 展示数据库
	 */
	public static final String DV="DV"; 
	/**
	 * 订单数据库
	 */
    public static final String OC="OC";  
    /**
	 * 主数据库
	 */
    public static final String IN="IN"; 
    /**
	 * 仓库数据库
	 */
    public static final String WC="WC"; 
    /**
	 * 订单预警数据库
	 */
    public static final String AC="AC";
}  
DataSourceContextHolder.java

package org.blue.ex.test;


/** 
 * 获得和设置上下文环境 主要负责改变上下文数据源的名称 
 *  
 * @author liujg 
 *  
 */  
public class DataSourceContextHolder {  
    private static final ThreadLocal contextHolder = new ThreadLocal(); // 线程本地环境  
  
    /**
     * 设置数据源类型
     * @param dataSourceType
     */
    public static void setDataSourceType(String dataSourceType) {  
        contextHolder.set(dataSourceType);  
    }  
  
    /**
     * 获取数据源类型  
     * @return
     */
    public static String getDataSourceType() {  
        return (String) contextHolder.get();  
    }  
  
    /**
     * 清除数据源类型
     */
    public static void clearDataSourceType() {  
        contextHolder.remove();  
    }  
  
}  
DynamicDataSource

package org.blue.ex.test;


import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;


/** 
 * 建立动态数据源 
 *  
 * @author LONGHUI_LUO 
 *  
 */  
public class DynamicDataSource extends AbstractRoutingDataSource {  
  
 protected Object determineCurrentLookupKey() {  
  // 在进行DAO操作前,通过上下文环境变量,获得数据源的类型  
  return DataSourceContextHolder.getDataSourceType();  
 }  
  
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值