SpringBoot + Druid + Dynamic Datasource 多数据源配置
SpringBoot + Druid + Dynamic Datasource 多数据源配置
- 1、依赖
- 2、application.yml
- 3、多数据源 Duid 自动装配详解
- 3.1、自动装配 spring.datasource.dynamic
- 3.2、自动装配多数据源 datasource
- 3.3、自动装配每个数据源下的 duid 配置
- 3.4、自动装配 StatViewServlet
- 3.5、自动装配 WebStatFilter
- 3.6、自动装配 AopPatterns
- 3.7、Filter 配置类
- 4、Druid 监控页面
- 4.1、首页
- 4.2、数据源列表
- 4.2、SQL 监控
- 4.3、SQL 防火墙
- 4.4、Web 应用
- 4.5、URI 监控
- 4.6、Web Session 监控
- 4.7、Spring 监控
- 4.8、JSON API
- 5、动态切换数据源
- 5.1、数据源枚举
- 5.2、Controller 层
- 5.3、AOP 根据入参自动切换数据源
- 6、日志输出效果
1、依赖
com.baomidou dynamic-datasource-spring-boot-starter 4.3.1 com.alibaba druid-spring-boot-starter com.alibaba druid-spring-boot-starter 1.2.24 MASTER("master"), SLAVE("slave"); private String value; DataSourceEnum(String value) { this.value = value; } public String getValue() { return value; } } @ApiImplicitParam(name = "envCode", value = "数据源标识", required = true, paramType = "query", example = "MASTER", dataTypeClass = DataSourceEnum.class), @ApiImplicitParam(name = "query", value = "查询字符串", required = true, paramType = "query", example = "select * from chinapostoffice limit 100", dataTypeClass = String.class), }) @GetMapping("/getChinaPostOffice ") public Response logger.info(">> query: {}", query); List list = customMapper.selectList(query); logger.info(">>> 总共 {} 条数据", list.size()); logger.info(">>> 数据: {}", JSONArray.from(list, JSONWriter.Feature.WriteMapNullValue).toJSONString(JSONWriter.Feature.WriteMapNullValue)); return new Response().success(JSONArray.from(list, JSONWriter.Feature.WriteMapNullValue)); }
5.3、AOP 根据入参自动切换数据源
DynamicDataSourceContextHolder 实现原理,可参考源码,解析得很详细了
@Aspect @Component // 确保在事务切面之前执行 @Order(Ordered.HIGHEST_PRECEDENCE) public class AutoSwitchDataSourceAop { private static final Logger logger = LoggerFactory.getLogger(AutoSwitchDataSourceAop.class); /** * 当前指定的默认数据源 */ @Value("${spring.datasource.dynamic.primary}") private String dynamicPrimaryDataSource; /** * 定义匹配需要切换数据源的方法的切点 * 匹配com.github.wxhnyfy.dynamicdatasource.controller包、com.github.wxhnyfy.dynamicdatasource.impl.service包下所有包含DataSourceEnum参数的方法 * 支持DataSourceEnum参数在任意参数位置(不限于第一个参数) * * @param joinPoint 切点 * @return 目标执行方法 * @throws Throwable 异常 */ @Around("execution(* com.github.wxhnyfy.dynamicdatasource.controller.*.*(com.github.wxhnyfy.dynamicdatasource.enums.DataSourceEnum, ..)) " + "|| execution(* com.github.wxhnyfy.dynamicdatasource.impl.service.*.*(com.github.wxhnyfy.dynamicdatasource.enums.DataSourceEnum, ..))") public Object around(ProceedingJoinPoint joinPoint) throws Throwable { MethodSignature signature = (MethodSignature) joinPoint.getSignature(); String methodName = signature.getMethod().getName(); logger.info("进入 SwitchDataSourceAspect 的方法名: {}", methodName); logger.debug("当前指定的默认数据源:{}", dynamicPrimaryDataSource); DataSourceEnum envCode = null; try { // 获取方法参数中的EnvCode值 envCode = extractEnvCode(joinPoint); // 切换数据源 if (envCode != null) { logger.info("数据库环境标识:{}", envCode); String previousDs = DynamicDataSourceContextHolder.peek(); logger.info("方法 [{}] 切换数据源: {} -> {}", methodName, previousDs, envCode.getValue()); DynamicDataSourceContextHolder.push(envCode.getValue()); } // 执行目标方法 return joinPoint.proceed(); } finally { // 清理数据源(恢复到默认数据源) if (envCode != null) { DynamicDataSourceContextHolder.clear(); } } } /** * 通过反射获取方法参数 * 自动识别DataSourceEnum类型的参数 * 支持任意位置的DataSourceEnum参数 * * @param joinPoint 切点 * @return DataSourceEnum参数 */ private DataSourceEnum extractEnvCode(ProceedingJoinPoint joinPoint) { MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Parameter[] parameters = signature.getMethod().getParameters(); // 遍历参数查找EnvCode类型的参数 for (int i = 0; i
6、日志输出效果
Mybatis-Plus 我们使用 org.apache.ibatis.logging.slf4j.Slf4jImpl 日志实现,配置对应的日志级别
mybatis-plus: mapper-locations: classpath:mapper/*.xml configuration: log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl logging: level: root: info # 注意,logback不支持**匹配 com.github.wxhnyfy.**.mapper: debug druid.sql.Statement: debug
日志输出效果如下图
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。