基于Spring+Mybatis的多数据源动态切换

Spring单数据源直接在<bean id="dataSource">下配置数据源的各种连接参数。但动态数据源需要配置个各个数据源例如ds1、ds2等。然后在dataSource中动态根据传递过来的参数动态调用不同的数据源。

1、当进行访问时,首先通过DbContextHolder.setDbType("ds1");设置需要使用的数据源。DbContextHolder就是一个用来存储数据源信息的类,其中通过ThreadLocal来记录数据源信息。

2、DynamicDataSource类集成Spring的AbstractRoutingDataSource类,通过determineCurrentLookupKey方法来获取数据源类型,如果没有对应的数据源则使用defaultTargetDataSource配置。

注意:当设置了数据源之后会一直使用该数据源进行连接,除非使用 DbContextHolder.setDbType重新设置数据源或使用DbContextHolder.clearDbType()清除,清除后使用defaultTargetDataSource进行连接。


1、配置文件

properties

ds1.driverClassName=oracle.jdbc.OracleDriver
ds1.url=jdbc:oracle:thin:@localhost:1521:ORCL
ds1.username=SSM
ds1.password=SSM

ds2.driverClassName=oracle.jdbc.OracleDriver
ds2.url=jdbc:oracle:thin:@10.27.192.43:1522:ORCL
ds2.username=FRAMEWORK_DEV
ds2.password=123456


xml

<bean id="dataSource" class="com.cnpc.framework.db.DynamicDataSource">
<property name="targetDataSources">
<map key-type="java.lang.String">
<entry key="ds1" value-ref="ds1" />
<entry key="ds2" value-ref="ds2" />
</map>
</property>
<property name="defaultTargetDataSource" ref="ds1" />
</bean>

<bean id="ds1" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${ds1.driverClassName}" />
<property name="url" value="${ds1.url}" />
<property name="username" value="${ds1.username}" />
<property name="password" value="${ds1.password}" />
</bean>
<bean id="ds2" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${ds2.driverClassName}" />
<property name="url" value="${ds2.url}" />
<property name="username" value="${ds2.username}" />
<property name="password" value="${ds2.password}" />
</bean>


2、Java文件
com.cnpc.framework.db.DynamicDataSource 源码

public class DynamicDataSource extends AbstractRoutingDataSource {

/**
* 取得当前使用那个数据源。
*/
@Override
protected Object determineCurrentLookupKey() {
return DbContextHolder.getDbType();
}


public Logger getParentLogger() {
// TODO Auto-generated method stub
return null;
}

}


DbContextHolder 源码

public class DbContextHolder
{
private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();

/**
* 设置当前数据库。
* @param dbType
*/
public static void setDbType(String dbType)
{
contextHolder.set(dbType);
}

/**
* 取得当前数据源。
* @return
*/
public static String getDbType()
{
String str = (String) contextHolder.get();
return str;
}

/**
* 清除上下文数据
*/
public static void clearDbType()
{
contextHolder.remove();
}

}


3、测试Code

public ModelAndView list(HttpServletRequest request, HttpServletResponse response) throws Exception {

DbContextHolder.setDbType("ds1");
List<DemoSysUser> list1 = demoSysUserService.getAll();
System.out.println(DbContextHolder.getDbType() + ".list.size()=" + list1.size());

DbContextHolder.setDbType("ds2");
List<DemoSysUser> list2 = demoSysUserService.getAll();
System.out.println(DbContextHolder.getDbType() + ".list.size()=" + list2.size());
DbContextHolder.clearDbType();

List<DemoSysUser> list = demoSysUserService.getAll();
ModelAndView mv = this.getAutoView().addObject("sysUserList", list);
return mv;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值