Spring Boot多数据源配置实战:Druid+MyBatisPlus整合指南
1. 项目概述在微服务架构盛行的当下Spring Boot项目经常需要同时连接多个数据库实例。最近在重构一个老旧的会员系统时就遇到了需要同时操作MySQL用户库和TiDB交易库的场景。经过多次踩坑终于实现了基于DruidMyBatisPlus的稳定多数据源方案。这个方案最大的特点在于完全兼容Spring Boot自动配置特性支持Druid连接池的各项监控指标保留MyBatisPlus的所有便捷操作事务管理清晰可控特别提醒多数据源配置中最容易犯的错误就是混淆Mapper接口和XML文件的路径配置这会导致经典的Invalid bound statement异常。2. 核心配置解析2.1 依赖管理关键点在pom.xml中需要特别注意这些依赖项properties spring-boot.version2.7.12/spring-boot.version druid.version1.2.16/druid.version mybatis-plus.version3.5.3.1/mybatis-plus.version /properties dependencies !-- 核心starter -- dependency groupIdcom.alibaba/groupId artifactIddruid-spring-boot-starter/artifactId version${druid.version}/version /dependency !-- MyBatisPlus必须单独指定版本 -- dependency groupIdcom.baomidou/groupId artifactIdmybatis-plus-boot-starter/artifactId version${mybatis-plus.version}/version exclusions exclusion groupIdcom.zaxxer/groupId artifactIdHikariCP/artifactId /exclusion /exclusions /dependency /dependencies这里有个重要细节MyBatisPlus默认使用HikariCP需要通过exclusions强制移除否则会与Druid产生冲突。2.2 配置文件陷阱application.yml的配置需要特别注意格式spring: datasource: master: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/master?useSSLfalse username: root password: 123456 druid: initial-size: 5 max-active: 20 validation-query: SELECT 1 slave: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql://localhost:3306/slave?useSSLfalse username: root password: 123456 druid: initial-size: 3 max-active: 15致命陷阱第一个数据源用url属性后续数据源必须用jdbc-url否则启动时会报jdbcUrl is required错误。这是Spring Boot自动配置机制的特殊要求。3. 数据源配置实战3.1 主数据源配置Configuration MapperScan(basePackages com.example.mapper.master, sqlSessionFactoryRef masterSqlSessionFactory) public class MasterDataSourceConfig { Bean Primary ConfigurationProperties(spring.datasource.master) public DataSource masterDataSource() { return DruidDataSourceBuilder.create().build(); } Bean Primary public SqlSessionFactory masterSqlSessionFactory( Qualifier(masterDataSource) DataSource dataSource) throws Exception { MybatisSqlSessionFactoryBean sessionFactory new MybatisSqlSessionFactoryBean(); sessionFactory.setDataSource(dataSource); sessionFactory.setMapperLocations( new PathMatchingResourcePatternResolver() .getResources(classpath:mapper/master/*.xml)); // 关键注入MyBatisPlus配置 MybatisConfiguration configuration new MybatisConfiguration(); configuration.setMapUnderscoreToCamelCase(true); configuration.setDefaultScriptingLanguage(MybatisXMLLanguageDriver.class); sessionFactory.setConfiguration(configuration); sessionFactory.setPlugins(new MybatisPlusInterceptor()); return sessionFactory.getObject(); } // 其他必要bean... }3.2 从数据源配置Configuration MapperScan(basePackages com.example.mapper.slave, sqlSessionFactoryRef slaveSqlSessionFactory) public class SlaveDataSourceConfig { Bean ConfigurationProperties(spring.datasource.slave) public DataSource slaveDataSource() { return DruidDataSourceBuilder.create().build(); } Bean public SqlSessionFactory slaveSqlSessionFactory( Qualifier(slaveDataSource) DataSource dataSource) throws Exception { MybatisSqlSessionFactoryBean sessionFactory new MybatisSqlSessionFactoryBean(); sessionFactory.setDataSource(dataSource); sessionFactory.setMapperLocations( new PathMatchingResourcePatternResolver() .getResources(classpath:mapper/slave/*.xml)); // 复用主数据源的MyBatisPlus配置 MybatisConfiguration configuration new MybatisConfiguration(); configuration.setMapUnderscoreToCamelCase(true); sessionFactory.setConfiguration(configuration); sessionFactory.setPlugins(new MybatisPlusInterceptor()); return sessionFactory.getObject(); } // 其他必要bean... }4. 事务管理方案4.1 单数据源事务直接在Service方法上使用Transactional即可Service RequiredArgsConstructor public class OrderService { private final OrderMapper orderMapper; // 主库Mapper Transactional public void createOrder(Order order) { orderMapper.insert(order); } }4.2 跨数据源事务需要引入JTA实现如AtomikosBean public JtaTransactionManager transactionManager() { return new JtaTransactionManager(); } // 使用时指定事务管理器 Transactional(transactionManager transactionManager) public void crossDatabaseOperation() { masterMapper.insert(...); slaveMapper.update(...); }性能警告分布式事务会显著降低系统吞吐量建议通过最终一致性方案替代。5. 监控配置技巧Druid的监控面板配置Bean public ServletRegistrationBeanStatViewServlet druidServlet() { ServletRegistrationBeanStatViewServlet reg new ServletRegistrationBean(); reg.setServlet(new StatViewServlet()); reg.addUrlMappings(/druid/*); reg.addInitParameter(loginUsername, admin); reg.addInitParameter(loginPassword, admin); return reg; } Bean public FilterRegistrationBeanWebStatFilter filterRegistrationBean() { FilterRegistrationBeanWebStatFilter reg new FilterRegistrationBean(); reg.setFilter(new WebStatFilter()); reg.addUrlPatterns(/*); reg.addInitParameter(exclusions, *.js,*.gif,*.jpg,*.css,/druid/*); return reg; }访问http://localhost:8080/druid即可查看SQL监控、URI监控等数据。6. 常见问题排查6.1 Mapper绑定失败错误现象BindingException: Invalid bound statement (not found)解决方案检查MapperScan的basePackages是否包含对应Mapper接口检查setMapperLocations路径是否包含XML文件确认XML中的namespace与Mapper接口全限定名一致6.2 事务不生效可能原因方法不是public自调用this.method()异常被catch未抛出数据库引擎不支持事务如MyISAM6.3 连接泄漏Druid监控面板查看activeCount持续增长检查代码中是否忘记关闭Connection/Statement/ResultSet7. 性能优化建议连接池参数调优druid: min-idle: 5 max-active: 50 max-wait: 3000 time-between-eviction-runs-millis: 60000 min-evictable-idle-time-millis: 300000MyBatisPlus二级缓存Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor()); interceptor.addInnerInterceptor(new CachingInnerInterceptor()); return interceptor; }SQL监控慢查询阈值druid: filter: stat: log-slow-sql: true slow-sql-millis: 10008. 扩展思考对于更复杂的多租户场景可以考虑动态数据源路由AbstractRoutingDataSourceSchema级别隔离MyBatisPlus租户插件在K8s环境中部署时建议使用ConfigMap管理数据源配置为每个Pod设置合理的连接池大小实现健康检查接口监控连接状态

相关新闻

大厂HR不敢说的秘密:技术简历上出现这3个词,直接进回收站

大厂HR不敢说的秘密:技术简历上出现这3个词,直接进回收站

你有多久没更新简历了?别急着改,先看一眼技能栏里那几个词。如果你还写着“精通功能测试”“负责用例执行”“熟悉QTP”,那最好先别投大厂。 这不是危言耸听。今年春招,某头部大厂HR私下跟我说了一句话:“现在收到测试…

2026/9/27 9:13:16 阅读更多 →
Unity UI点击检测:EventSystem与射线检测的5个实战技巧

Unity UI点击检测:EventSystem与射线检测的5个实战技巧

1. 项目概述:为什么UI点击检测是Unity开发者的必修课在Unity里做UI交互,点击检测是绕不开的第一道坎。看起来简单,不就是点一下按钮有反应吗?但实际开发中,尤其是项目规模变大、UI层级复杂、特效满天飞的时候&#xff…

2026/9/28 22:14:58 阅读更多 →
YOLOv10在密集行人检测中的优化实践

YOLOv10在密集行人检测中的优化实践

1. 项目概述:当YOLOv10遇上密集行人检测密集场景下的行人检测一直是计算机视觉领域的硬骨头。去年在上海外滩实测某商业检测系统时,面对每秒30帧的4K视频流,传统检测器在人群密度超过3人/㎡时,漏检率直接飙升至40%以上。这正是我们…

2026/9/28 19:37:09 阅读更多 →

最新新闻

Codex本地自定义Agent配置指南:AGENTS.md与config.toml优先级详解

Codex本地自定义Agent配置指南:AGENTS.md与config.toml优先级详解

1. 为什么要在本地折腾 Codex 自定义 AgentCodex 这个工具刚出来的时候,大部分人就是拿它当个命令行版的代码补全用——敲个codex进去,问两句,拿点代码片段走人。但真正把它用起来的人会发现,默认配置下的 Codex 其实是个“半成品…

2026/9/30 8:22:48 阅读更多 →
深度学习优化器选型与调参实战:从SGD到AdamW,解决模型收敛与泛化难题

深度学习优化器选型与调参实战:从SGD到AdamW,解决模型收敛与泛化难题

经常有人问我:“我的模型为什么不收敛?”、“同样的代码换了数据之后效果怎么差了这么多?”。我第一个反问的往往是:“你用的哪个优化器?”,然后很多人就愣住了。说实话,在深度学习的整个训练闭…

2026/9/30 8:22:48 阅读更多 →
目标检测全解析:从R-CNN到YOLOv8的算法演进与实战指南

目标检测全解析:从R-CNN到YOLOv8的算法演进与实战指南

我第一次真正被目标检测震撼到,是在实验室里跑通YOLOv1的时候。一张布满行人和车辆的街景图,模型一口气框出了几十个目标,每个框上都带着类别标签和置信度。那种“机器真的能看懂画面里有什么、在哪儿”的感觉,直到今天回想起来都…

2026/9/30 8:22:48 阅读更多 →
基于Node.js+Vue的固定资产管理系统:Excel导入与可视化实战

基于Node.js+Vue的固定资产管理系统:Excel导入与可视化实战

我最早接手这个项目时,电梯厂财务科拿给我的是一张将近五千行的Excel表格,里面有型号、编码、购入日期、使用部门、当前状态,但同一台设备在不同年份的表格里名字都不一样,有的叫"三菱电梯"有的叫"三菱"&…

2026/9/30 8:22:48 阅读更多 →
团队级CLAUDE.md实战:打造统一项目智能指南

团队级CLAUDE.md实战:打造统一项目智能指南

最近好几个团队负责人跑来问我同一个问题:个人 CLAUDE.md 确实好用,可我们十个人共用一个仓库,每个人的 CLAUDE.md 都不一样,AI 到底该听谁的?这个问题的答案,就是这篇要聊的核心——共享团队 CLAUDE.md&am…

2026/9/30 8:22:48 阅读更多 →
AI项目总翻车?四个风险域框架帮你系统排查

AI项目总翻车?四个风险域框架帮你系统排查

1. 从“四个风险域”说起:为什么AI项目总在同一个地方翻车做AI项目这些年,我越来越觉得,真正让项目翻车的往往不是模型不够强,而是团队对风险的认知太窄。很多人一提AI风险,脑子里只有“模型会不会胡说八道”这一件事&…

2026/9/30 8:21:47 阅读更多 →

日新闻

Base64 图片头部特征识别:从文件头到格式判断的完整指南

Base64 图片头部特征识别:从文件头到格式判断的完整指南

1. 项目概述:为什么说看懂 base64 图片头部是基本功这几年跟 base64 打交道的机会越来越多,后端接口返回图片、前端渲染验证码、小程序里存小图、还有一些老系统导出报表,动不动就给你一段长到怀疑人生的 base64 字符串。很多人拿到字符串就直…

2026/9/30 0:00:35 阅读更多 →
Java公交站牌广告管理系统:JSP+Servlet+MySQL实战落地指南

Java公交站牌广告管理系统:JSP+Servlet+MySQL实战落地指南

简介:本资源是一份面向Java初学者与课程设计学生的公交站牌广告灯箱管理系统毕业设计文档,聚焦城市公共广告资源信息化管理痛点,提供从需求分析到技术实现的完整方案。文档采用标准学术论文结构,含摘要、英文摘要、目录及五章正文…

2026/9/30 0:00:35 阅读更多 →
用 Redis Lua 构建大模型 API 多租户原子配额治理体系

用 Redis Lua 构建大模型 API 多租户原子配额治理体系

我去年年底接了一个内部 AI 平台的治理需求,背景很直接:公司把 DeepSeek、MiniMax 这类大模型 API 统一封装成内部网关,开放给几个业务团队用。结果第一个月账单出来,额度直接超了 4 倍。仔细查日志,发现原因并不复杂—…

2026/9/30 0:00:35 阅读更多 →

周新闻

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解 【免费下载链接】spirula-studio Cross-vendor 3D Gaussian Splatting trainer - video to splat to mesh, Vulkan or CUDA. 项目地址: https://gitcode.com/GitHub_Trending/sp/spirula-studio Sp…

2026/9/29 8:16:59 阅读更多 →
SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南 模板网站太丑不够用?别急着加滤镜,那是治标不治本。很多老板盯着后台流量掉得眼红,却还在纠结首页Banner的圆角是不是3像素。这就像穿着西装去挖土,姿势不对,努力白费。我整理这份 速查手册…

2026/9/29 16:41:41 阅读更多 →
FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏 【免费下载链接】FireRed-OpenStoryline FireRed-OpenStoryline is an AI video editing agent that transforms manual editing into intention-driven directing through natural language …

2026/9/29 8:24:48 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/29 19:29:29 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/29 5:58:00 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/29 3:55:56 阅读更多 →