单数据源访问多数据库的路由开发

在某些可以配置多站点的开发框架中,如果每个站点单独配置了单独的数据库。那么利用单一数据源根据不同的站点切换不同的数据库比较方便。

在这里展示了spring框架下的解决方案。利用了spring的org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource

站点路由的datasource SiteRoutingDataSource

1
2
3
4
5
6
7
8
9
10
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
public class SiteRoutingDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return SiteContextHolder.getSiteCode();
}
}

用来判定当前站点的工具类SiteContextHolder

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import org.springframework.util.Assert;
public class SiteContextHolder {
private static final ThreadLocal<String> contextHolder =
new ThreadLocal<String>();
public static void setSiteCode(String siteCode) {
Assert.notNull(siteCode, "siteCode cannot be null");
contextHolder.set(siteCode);
}
public static String getSiteCode() {
return (String) contextHolder.get();
}
public static void clearSiteCode() {
contextHolder.remove();
}
}

spring的xml配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<bean id="hgc"
class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass">
<value>${hgc.datasource.driverClassName}</value>
</property>
<property name="jdbcUrl">
<value>${hgc.datasource.url}</value>
</property>
<property name="user">
<value>${hgc.datasource.username}</value>
</property>
<property name="password">
<value>${hgc.datasource.password}</value>
</property>
</bean>
<bean id="ahpu"
class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass">
<value>${ahpu.datasource.driverClassName}</value>
</property>
<property name="jdbcUrl">
<value>${ahpu.datasource.url}</value>
</property>
<property name="user">
<value>${ahpu.datasource.username}</value>
</property>
<property name="password">
<value>${ahpu.datasource.password}</value>
</bean>
<bean id="dataSource" class="SiteRoutingDataSource">
<property name="targetDataSources">
<map key-type="java.lang.String">
<entry key="hgc" value-ref="hgc"/>
<entry key="ahpu" value-ref="ahpu"/>
</map>
</property>
<property name="defaultTargetDataSource" ref="ahpu"/>
</bean>

在使用过程中 通过 SiteContextHolder.setSiteCode(CODE);来进行数据源选择。在切换数据库之前,需要先SiteContextHolder.clearSiteCode();再进行切换

一个java web程序员,希望自己两年之内能成为data scientist,正在找工作