[java][framework][ssm][转载] SSM框架配置动态多数据源
转载自: http://elvis4139.iteye.com/blog/2278760
Spring单数据源直接在<bean id="dataSource">下配置数据源的各种连接参数。但动态数据源需要配置个各个数据源例如oracle、mysql等。然后在dataSource中动态根据传递过来的参数动态调用不同的数据源。
1、当进行访问时,首先通过DbContextHolder.setDbType("mysql");设置需要使用的数据源。DbContextHolder就是一个用来存储数据源信息的类,其中通过ThreadLocal来记录数据源信息。
2、DynamicDataSource类集成Spring的AbstractRoutingDataSource类,通过determineCurrentLookupKey方法来获取数据源类型,如果没有对应的数据源则使用defaultTargetDataSource配置。
注意:当设置了数据源之后会一直使用该数据源进行连接,除非使用 DbContextHolder.setDbType("oracle")重新设置数据源或使用DbContextHolder.clearDbType()清除,清除后使用defaultTargetDataSource属性指向的数据源进行连接。
properties
spring.datasource.oracle.driver-class-name=oracle.jdbc.OracleDriver spring.datasource.oracle.url= spring.datasource.oracle.username= spring.datasource.oracle.password= spring.datasource.mysql.driver-class-name=com.mysql.jdbc.Driver spring.datasource.mysql.url= spring.datasource.mysql.username= spring.datasource.mysql.password=
xml
<bean id="oracle" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
<property name="driverClassName" value="${spring.datasource.oracle.driver-class-name}" />
<property name="jdbcUrl" value="${spring.datasource.oracle.url}" />
<property name="username" value="${spring.datasource.oracle.username}" />
<property name="password" value="${spring.datasource.oracle.password}" />
</bean>
<bean id="mysql" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
<property name="driverClassName" value="${spring.datasource.mysql.driver-class-name}" />
<property name="jdbcUrl" value="${spring.datasource.mysql.url}" />
<property name="username" value="${spring.datasource.mysql.username}" />
<property name="password" value="${spring.datasource.mysql.password}" />
</bean>
<bean id="hikari" class="com.keen.coinpay.app.common.config.ds.DynamicDataSource">
<property name="targetDataSources">
<map key-type="java.lang.String">
<entry key="oracle" value-ref="oracle" />
<entry key="mysql" value-ref="mysql" />
</map>
</property>
<property name="defaultTargetDataSource" ref="oracle" />
</bean>
com.keen.coinpay.app.common.config.ds.DynamicDataSource
package com.keen.coinpay.app.common.config.ds;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DbContextHolder.getDbType();
}
}
com.keen.coinpay.app.common.config.ds.DbContextHolder
package com.keen.coinpay.app.common.config.ds;
public class DbContextHolder {
private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();
public static void setDbType(String dbType) {
contextHolder.set(dbType);
}
public static String getDbType() {
String str = (String) contextHolder.get();
return str;
}
public static void clearDbType() {
contextHolder.remove();
}
}
测试
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;
}
注意: 如果在配置了不同类型(MySQL/Oracle)动态数据源的情况下同时使用PageHelper做分页, 则需要给PageHelper配置参数[autoRuntimeDialect=true], 不然无法正确识别数据库Dialect, 进而无法按照正确的规则正确拼写分页SQL

浙公网安备 33010602011771号