spring mybatis多数据源配置

spring在管理数据源的时候是直接使用DataSourceTransactionManager,并将datasource放入进去,所以在多数据源的时候,只要在这个时间节点前,改变DataSource就行了。

spring的多数据源支持类是一个叫AbstractRoutingDataSource的抽象类

捡几个重要属性和方法说一下

targetDataSources目前数据源是一个map集合

defaultTargetDataSource默认数据源

lenientFallback当目标数据源未找到时,是否使用默认数据源,默认为true

resolvedDataSources和resolvedDefaultDataSource这两个属性是将目标数据源通过afterPropertiesSet方法进行重新赋值

主要的方式是determineTargetDataSource

这个方法是在目标查询是确定该数据源是使用哪个数据源

determineCurrentLookupKey获取目标数据源,是一个抽象方法,如果我们动态该变数据源的时候,就需要重写这个方法

所以在这种情况下,我们需要写一个动态获取数据源的类DynamicDataSource

public class DynamicDataSource extends AbstractRoutingDataSource {

@Override

protected Object determineCurrentLookupKey() {

return DbContextHolder.getDb();

}

@Override

protected DataSource determineTargetDataSource() {

DataSource dataSource = super.determineTargetDataSource();

return dataSource;

}

}

这个类继承AbstractRoutingDataSource,并重写其中的determineCurrentLookupKey方法,因为这个方法要获取数据源的名称,那么再定义个数据源获取类DbContextHolder

public class DbContextHolder {

private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();

public static void setDb(String db) {

contextHolder.set(db);

}

public static String getDb() {

return  contextHolder.get();

}

public static void cleanDb() {

contextHolder.remove();

}

}

这样既可

然后在配置文件里面新增多数据源配置

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">

<property name="driverClassName" value="${master.driverClassName}" />

<property name="url" value="${master.url}" />

<property name="username" value="${master.username}" />

<property name="password" value="${master.password}" />

<property name="initialSize" value="0" />

<!-- 连接池最大使用连接数量 -->

<property name="maxActive" value="40" />

<!-- 连接池最大空闲 -->

<property name="maxIdle" value="40" />

<!-- 连接池最小空闲 -->

<property name="minIdle" value="0" />

<!-- 获取连接最大等待时间 -->

<property name="maxWait" value="60000" />

</bean>

<bean id="dataSourceAssist1" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">

<property name="driverClassName" value="${assist.driverClassName}" />

<property name="url" value="${assist.url}" />

<property name="username" value="${assist.username}" />

<property name="password" value="${assist.password}" />

<property name="initialSize" value="0" />

<!-- 连接池最大使用连接数量 -->

<property name="maxActive" value="40" />

<!-- 连接池最大空闲 -->

<property name="maxIdle" value="40" />

<!-- 连接池最小空闲 -->

<property name="minIdle" value="0" />

<!-- 获取连接最大等待时间 -->

<property name="maxWait" value="60000" />

</bean>

<bean id="dataSourceNew2" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">

<property name="driverClassName" value="${new.driverClassName}" />

<property name="url" value="${new.url}" />

<property name="username" value="${new.username}" />

<property name="password" value="${new.password}" />

<property name="initialSize" value="0" />

<!-- 连接池最大使用连接数量 -->

<property name="maxActive" value="40" />

<!-- 连接池最大空闲 -->

<property name="maxIdle" value="40" />

<!-- 连接池最小空闲 -->

<property name="minIdle" value="0" />

<!-- 获取连接最大等待时间 -->

<property name="maxWait" value="60000" />

</bean>

多数据源配置完毕后,配置动态获取数据源的bean

<bean id="dynamicDataSource" class="com.fyz.boss.common.datasouces.DynamicDataSource">  

        <property name="targetDataSources">  

            <map key-type="java.lang.String">  

                <entry key="dataSource" value-ref="dataSource" />  

                <entry key="dataSourceAssist1" value-ref="dataSourceAssist1" /> 

                <entry key="dataSourceNew2" value-ref="dataSourceNew2" />

            </map>

        </property>  

        <property name="defaultTargetDataSource" ref="dataSource" />  

  </bean> 

这个时候,将SqlSessionFactoryBean和DataSourceTransactionManager的DataSource属性引用为动态数据源的bean

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">

<property name="dataSource" ref="dynamicDataSource" />

<property name="configLocation" value="classpath:mybatis/mybatis-config.xml" />

<property name="mapperLocations">

<list>

<value>classpath:com/fyz/boss/**/*.xml</value>

</list>

</property>

</bean>

<bean id="txManager"

class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

<property name="dataSource" ref="dynamicDataSource" />

</bean>

测试环节

@Test

public void testDb() {

System.out.println("------------------");

if(memberServiceImpl == null){

System.out.println("123");

}

DbContextHolder.setDb("dataSourceNew2");  

Member m = new Member();

m.setAccountName("22213");

m.setMemberName("gui");

System.out.println(DbContextHolder.getDb());

System.out.println(memberServiceImpl.add(m));

//DbContextHolder.setDb("dataSource");

}

这个时候可以动态的改变数据源了,如果在配置文件中将lenientFallback属性设置为false的话,测试的配置中如果找不到dataSourceNew2将会报错

猜你喜欢

转载自lovewen-2004.iteye.com/blog/2372596