[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

posted @ 2017-11-28 11:43  mrathena  阅读(1053)  评论(0编辑  收藏  举报