springmvc+mybatis配置多数据源

要使用SpringMVC配置多个数据源,最主要的类是MultipleDataSource
首先在spring.xml中增加一个dataSource的bean

"dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"
          p:url="${jdbc.url}"
          p:username="${jdbc.username}"
          p:password="${jdbc.password}"
          p:filters="${jdbc.filters}"
          p:maxActive="${jdbc.maxActive}"
          p:initialSize="${jdbc.initialSize}"
          p:maxWait="${jdbc.maxWait}"
          p:minIdle="${jdbc.minIdle}"
          p:timeBetweenEvictionRunsMillis="${jdbc.timeBetweenEvictionRunsMillis}"
          p:minEvictableIdleTimeMillis="${jdbc.minEvictableIdleTimeMillis}"
          p:validationQuery="${jdbc.validationQuery}"
          p:testWhileIdle="${jdbc.testWhileIdle}"
          p:testOnBorrow="${jdbc.testOnBorrow}"
          p:testOnReturn="${jdbc.testOnReturn}"/>

    "dataSource2" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"
        p:url="${jdbc.url2}"
        p:username="${jdbc.username}"
        p:password="${jdbc.password}"
        p:filters="${jdbc.filters}"
        p:maxActive="${jdbc.maxActive}"
        p:initialSize="${jdbc.initialSize}"
        p:maxWait="${jdbc.maxWait}"
        p:minIdle="${jdbc.minIdle}"
        p:timeBetweenEvictionRunsMillis="${jdbc.timeBetweenEvictionRunsMillis}"
        p:minEvictableIdleTimeMillis="${jdbc.minEvictableIdleTimeMillis}"
        p:validationQuery="${jdbc.validationQuery}"
        p:testWhileIdle="${jdbc.testWhileIdle}"
        p:testOnBorrow="${jdbc.testOnBorrow}"
        p:testOnReturn="${jdbc.testOnReturn}"/>

此处设置了两个数据源,然后新增一个MultipleDataSource的bean

    id="multipleDataSource" class="com.ats.configuration.MultipleDataSource">
        <property name="targetDataSources">
            "java.lang.String">
                "dataSource" value-ref="dataSource"/>
                "dataSource2" value-ref="dataSource2"/>
            
        property>
        <property name="defaultTargetDataSource" ref="dataSource"/>
    

记得SqlSessionFactoryBean中的dataSource-ref要改成multipleDataSource,如果还是用回dataSource会导致spring的事务管理失效

事务管理配置

id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
    p:dataSource-ref="multipleDataSource"/>

新建一个类继承AbstractRoutingDataSource

public class MultipleDataSource extends AbstractRoutingDataSource {

    @Override
    protected Object determineCurrentLookupKey() {
        return CustomerContextHolder.getCustomerType();
    }

}

新建CustomerContextHolder类

public class CustomerContextHolder {

    public static final String DATA_SOURCE_MYSQL = "dataSource";

    public static final String DATA_SOURCE_MSSQL = "dataSource2";

    //用ThreadLocal来设置当前线程使用哪个dataSource
    private static final ThreadLocal contextHolder = new ThreadLocal<>();

    public static void setCustomerType(String customerType) {
        contextHolder.set(customerType);
    }

    public static String getCustomerType() {
        String dataSource = contextHolder.get();
        if (StringUtils.isEmpty(dataSource)) {
            return DATA_SOURCE_MYSQL;
        } else {
            return dataSource;
        }
    }

    public static void clearCustomerType() {
        contextHolder.remove();
    }
}

最后通过AOP转换数据源,这样可以减少对业务代码的入侵

@Component
@Aspect
public class SystemRunTimeAspect {
    @Pointcut("execution(* com.ats.controller.FakeController.*(..))")//按照你实际的需要切入的方法
    public void changeDatabase(){}

    @Around("changeDatabase()")
    public Object database(ProceedingJoinPoint pjp) throws Throwable {
        CustomerContextHolder.setCustomerType(CustomerContextHolder.DATA_SOURCE_MSSQL);
        Object p = pjp.proceed();
        CustomerContextHolder.clearCustomerType();
        return p;
    }
}

你可能感兴趣的:(学习笔记,Java)