SpringBoot+MyBatis利用切面的方式配置多数据源,同时用druid监控sql
重点1、AOP相关的知识,这里主要是切点的定位
2、重写AbstractRoutingDataSource的determineCurrentLookupKey方法
3、数据源的切换
在分包的基础上增加切面相关的配置

@ConfigurationProperties(prefix = "spring.datasource.db1")
public DataSource db1() {
return DataSourceBuilder.create().type(DruidDataSource.class).build();
}
@Bean(name = "db2")
@ConfigurationProperties(prefix = "spring.datasource.db2")
public DataSource db2(){
return DataSourceBuilder.create().type(DruidDataSource.class).build();
}
@Primary
@Bean("dynamicDatasource")
public DataSource dynamicDatasource() {
DynamicDatasource dynamicDatasource = new DynamicDatasource();
// 配置默认数据源
dynamicDatasource.setDefaultTargetDataSource(db1());
// 配置多数据源
Map
2、db1
@Configuration
@MapperScan(basePackages = "路径",sqlSessionFactoryRef = "mysqlSqlSessionFactory")
public class DB1DSConfig {
static final String MAPPER_LOCATION = "classpath:mapper/mysql
@Configuration
@MapperScan(basePackages = "路径",sqlSessionFactoryRef = "mysqlSqlSessionFactory")
public class DB2DSConfig {
static final String MAPPER_LOCATION = "classpath:mapper/mysql
public class DatasourceContextHolder {
private static final Logger logger = LoggerFactory.getLogger(DatasourceContextHolder.class);
private static final ThreadLocal contextHolder = new ThreadLocal<>();
public static void setDatasource(String name) {
logger.info("切换到[{}]数据源", name);
contextHolder.set(name);
}
public static String getDatasource() {
return contextHolder.get();
}
public static void clearDatasource() {
contextHolder.remove();
}
}
切换数据源
AbstractRoutingDataSource类是Spring为方便的在项目中实现动态切换数据源而提供的一个抽象类, 我们只需要实现上面的这个抽象方法 即可 , 该方法用于返回当前需要切换的数据源的key;
public class DynamicDatasource extends AbstractRoutingDataSource {
private static final Logger logger = LoggerFactory.getLogger(DynamicDatasource.class);
// public DynamicDatasource(Datasource datasource, Map
切面拦截切换数据源
@Component
@Aspect
@Order(-1)// 使该切面调用优先于AbstractRoutingDataSource的determineCurrentLookupKey()
public class DynamicDatasourceAspect {
@Pointcut("@annotation(数据源对象的路径,即Datasource的路径)")
public void pointCut() {
System.out.println("使用[@Pointcut]定义切入点");
}
@Before("pointCut()")
public void before(JoinPoint joinPoint) {
try {
// 获取当前访问的class
Class> aClass = joinPoint.getTarget().getClass();
// 获取当前访问的method
String methodName = joinPoint.getSignature().getName();
// 获取方法的参数类型数组
Class[] parameterTypes = ((MethodSignature) joinPoint.getSignature()).getParameterTypes();
// 获取方法对象
Method method = aClass.getDeclaredMethod(methodName, parameterTypes);
Datasource datasource = method.getAnnotation(Datasource.class);
if (null!=datasource){
DatasourceContextHolder.setDatasource(datasource.value());
}
} catch (Exception e) {
e.printStackTrace();
}finally {
DatasourceContextHolder.clearDatasource();
}
}
@After("pointCut()")
public void after() {
System.out.println("after");
DatasourceContextHolder.clearDatasource();
}
}
切点的路径即,上文动态的数据源对象的路径,也可以定义在service层,但是我这边只有定义在数据源对象这里才能实现切换
dao层配置指定数据源1、db1
@Datasource(value = "db1")
2、db2
@Datasource(value = "db2")暑期编程PK赛 得CSDN机械键盘等精美礼品!



