spring 动态切换数据源 多数据库

1.背景

  • 对于数据量在1千万,单个mysql数据库就可以支持,但是如果数据量大于这个数的时候,例如1亿,那么查询的性能就会很低。此时需要对数据库做水平切分,常见的做法是按照用户的账号进行hash,然后选择对应的数据库。
  • 水平切分图,数据落入不同的库中

2.实现

2.1示意图

先来看下大致示意图:

  • 图1是比较常见的情况,单个数据库
  • 图2展示了web应用和数据库之间的一个中间层,这个中间层去选择使用哪个数据库。
2.2数据库配置
  • 首先我们需要配置多个数据源,我是用xml进行配置的其他方法大同小异,就是多建立了几个bean。
	<bean id="parentDataSource" abstract="true"
		  class="org.apache.tomcat.jdbc.pool.DataSource"
		  destroy-method="close"
		  p:maxWait="10000"
		  p:removeAbandoned="true"
		  p:removeAbandonedTimeout="180"
		  p:connectionProperties="clientEncoding=UTF-8"
		  p:validationQuery="SELECT 1"
		  p:validationInterval="30000"
		  p:testOnBorrow="false"
		  p:testOnReturn="false"
		  p:testWhileIdle="true"
		  p:timeBetweenEvictionRunsMillis="10000"
		  p:minEvictableIdleTimeMillis="60000"
		  p:logAbandoned="false"
		  p:defaultAutoCommit="true" />

	<bean id="dataSource" parent="parentDataSource"
		  p:driverClassName="com.mysql.jdbc.Driver"
		  p:username="${jdbc.user}"
		  p:password="${jdbc.password}"
		  p:initialSize="20"
		  p:maxActive="200"
		  p:maxIdle="200"
		  p:minIdle="5"/>

	<bean id="childDataSource1" parent="dataSource">
		<property name="url" value="${jdbc.url1}" />
	</bean>

	<bean id="childDataSource2" parent="dataSource">
		<property name="url" value="${jdbc.url2}" />
	</bean>
	
  • 这里我建了两个数据源bean的id分别为childDataSource1,childDataSource2,为了方便起见,这里只有数据库的url不同,故都继承了dataSource。
2.3 java实现

先把定义的多个数据库bean放一放,先来看下spring中对动态选择数据源的支持。

  • 在spring中有一个抽象类AbstractRoutingDataSource类,通过这个类可以实现动态选择数据源。来看下这个类的成员变量
    private Map<Object, Object> targetDataSources;
    private Object defaultTargetDataSource;
    private Map<Object, DataSource> resolvedDataSources;
  • targetDataSources中保存了key和数据库连接的映射关系,defaultTargetDataSource表示默认的链接,resolvedDataSources这个数据结构是通过targetDataSources构建而来,存储的结构也是数据库标识和数据源的映射关系。
  • 下面需要继承AbstractRoutingDataSource类,实现我们自己的数据库选择逻辑DataSourceSwitcher类,先上代码:
public class DataSourceSwitcher extends AbstractRoutingDataSource{
   

    private static final Logger LOGGER = LoggerFactory.getLogger("INTERACTIVE_LOGGER");

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


    public static void<
评论 25
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值