之前的那种方式(https://blog.csdn.net/weixin_43240792/article/details/88645099)需要在service中重复写相同的方法,在每个方法上指明是用的那个数据源,现在的这种方式不需写重复的方法,只需在controller调用service方法前指明使用哪个数据源。配置如下:
package com.inspur.dsp.mybatisconfig;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import com.baomidou.mybatisplus.plugins.OptimisticLockerInterceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.baomidou.mybatisplus.entity.GlobalConfiguration;
import com.baomidou.mybatisplus.mapper.LogicSqlInjector;
import com.baomidou.mybatisplus.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.plugins.PerformanceInterceptor;
import org.springframework.context.annotation.Primary;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
/**
* Mybatis配置
* @author jamesli
* @date 2017-05-26
*/
@EnableTransactionManagement
@Configuration
@MapperScan(basePackages = {"com.inspur.dsp.**.dao", "mapper"}) //dao、mapper路径
public class MybatisConfig {
/**
* mybatis-plus分页插件<br>
* 文档:http://mp.baomidou.com<br>
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
paginationInterceptor.setLocalPage(true);// 开启 PageHelper 的支持
return paginationInterceptor;
}
/**
* mybatis-plus SQL执行效率插件【生产环境可以关闭】
*/
@Bean
public PerformanceInterceptor performanceInterceptor() {
return new PerformanceInterceptor();
}
@Bean(name="db1")
@ConfigurationProperties("spring.datasource.druid.db1") //需跟配置文件中的写法一样
public DataSource db1() {
return DruidDataSourceBuilder.create().build();
}
@Bean(name="db2")
@ConfigurationProperties("spring.datasource.druid.db2")
public DataSource db2() {
return DruidDataSourceBuilder.create().build();
}
@Bean(name="db3")
@ConfigurationProperties("spring.datasource.druid.db3")
public DataSource db3() {
return DruidDataSourceBuilder.create().build();
}
@Bean
@Primary
public DynamicDataSource dataSource(@Qualifier("db1") DataSource db1, @Qualifier("db2") DataSource db2,@Qualifier("db3") DataSource db3) {
Map<Object, Object> targetDataSources = new HashMap<>();
targetDataSources.put(DataSourceNames.BWCONVERGE, db1);
targetDataSources.put(DataSourceNames.DFCONVERGE, db2);
targetDataSources.put(DataSourceNames.BWRETURN, db3);
return new DynamicDataSource(db1, targetDataSources);
}
@Bean
public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory){
return new SqlSessionTemplate(sqlSessionFactory);
}
@Bean
public GlobalConfiguration globalConfiguration() {
GlobalConfiguration conf = new GlobalConfiguration(new LogicSqlInjector());
conf.setLogicDeleteValue("-1");
conf.setLogicNotDeleteValue("1");
conf.setIdType(0);
//conf.setMetaObjectHandler(new MyMetaObjectHandler());
conf.setDbColumnUnderline(true);
conf.setRefresh(true);
return conf;
}
}
package com.inspur.dsp.mybatisconfig;
import org.apache.commons.lang.ArrayUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import java.util.Map;
@Aspect
@Component
@Order(value = -100) //@Order设置的足够小是为了让他先执行
public class DataSourceAspect {
@Pointcut("execution(* com.inspur.dsp.statistics.service..*.*(..))")
public void dataSourcePointCut() {
}
@Before("dataSourcePointCut()")
public void changeDatasource(JoinPoint joinPoint){
Object[] args = joinPoint.getArgs();
Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
//获取调用service方法传入的所有参数
String[] parameterNames = methodSignature.getParameterNames();
//int systemCode = ArrayUtils.indexOf(parameterNames, "systemCode");
//controller调用service方法时传入的带有数据源标志的参数名,这里是param,传入的参数也应该是param
int indexNum = ArrayUtils.indexOf(parameterNames, "param");
//int systemCode =Integer.valueOf(String.valueOf(systemCodemap.get("systemCode")));
if(indexNum!=-1){
Map<String,Object> systemCodemap = (Map<String,Object>)args[indexNum];
//标志数据源的key
String arg = String.valueOf(systemCodemap.get("datasource"));
DynamicDataSource.setDataSource(arg);
}
}
@After("dataSourcePointCut()")
public void clearDatasource(){
DynamicDataSource.clearDataSource();
}
}
//根据传入的数据源标志匹配对应的数据源
public interface DataSourceNames {
String DFCONVERGE="29";
String BWCONVERGE="72";
String BWRETURN="65";
}
package com.inspur.dsp.mybatisconfig;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import javax.sql.DataSource;
import java.util.Map;
public class DynamicDataSource extends AbstractRoutingDataSource {
private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();
public DynamicDataSource(DataSource defaultTargetDataSource, Map<Object, Object> targetDataSources) {
super.setDefaultTargetDataSource(defaultTargetDataSource);
super.setTargetDataSources(targetDataSources);
super.afterPropertiesSet();
}
@Override
protected Object determineCurrentLookupKey() {
return getDataSource();
}
public static void setDataSource(String dataSource) {
contextHolder.set(dataSource);
}
public static String getDataSource() {
return contextHolder.get();
}
public static void clearDataSource() {
contextHolder.remove();
}
}
使用方法:在controller指明【要求serviceImpl中方法接收指明数据源的参数名称必须是param(因为上面设置的是param)】
SpringBoot + Mybatis plus 实现多数据源整合_Dai的博客-CSDN博客
springboot+druid+mybatis plus的多数据源配置 - puretuo - 博客园