news 2026/7/22 7:23:30

Spring Boot多数据源配置实战:Druid+MyBatisPlus整合指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Spring Boot多数据源配置实战:Druid+MyBatisPlus整合指南

1. 项目概述

在微服务架构盛行的当下,Spring Boot项目经常需要同时连接多个数据库实例。最近在重构一个老旧的会员系统时,就遇到了需要同时操作MySQL用户库和TiDB交易库的场景。经过多次踩坑,终于实现了基于Druid+MyBatisPlus的稳定多数据源方案。

这个方案最大的特点在于:

  • 完全兼容Spring Boot自动配置特性
  • 支持Druid连接池的各项监控指标
  • 保留MyBatisPlus的所有便捷操作
  • 事务管理清晰可控

特别提醒:多数据源配置中最容易犯的错误就是混淆Mapper接口和XML文件的路径配置,这会导致经典的"Invalid bound statement"异常。

2. 核心配置解析

2.1 依赖管理关键点

在pom.xml中需要特别注意这些依赖项:

<properties> <spring-boot.version>2.7.12</spring-boot.version> <druid.version>1.2.16</druid.version> <mybatis-plus.version>3.5.3.1</mybatis-plus.version> </properties> <dependencies> <!-- 核心starter --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>${druid.version}</version> </dependency> <!-- MyBatisPlus必须单独指定版本 --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>${mybatis-plus.version}</version> <exclusions> <exclusion> <groupId>com.zaxxer</groupId> <artifactId>HikariCP</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?useSSL=false 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?useSSL=false 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实现(如Atomikos):

@Bean public JtaTransactionManager transactionManager() { return new JtaTransactionManager(); } // 使用时指定事务管理器 @Transactional(transactionManager = "transactionManager") public void crossDatabaseOperation() { masterMapper.insert(...); slaveMapper.update(...); }

性能警告:分布式事务会显著降低系统吞吐量,建议通过最终一致性方案替代。

5. 监控配置技巧

Druid的监控面板配置:

@Bean public ServletRegistrationBean<StatViewServlet> druidServlet() { ServletRegistrationBean<StatViewServlet> reg = new ServletRegistrationBean<>(); reg.setServlet(new StatViewServlet()); reg.addUrlMappings("/druid/*"); reg.addInitParameter("loginUsername", "admin"); reg.addInitParameter("loginPassword", "admin"); return reg; } @Bean public FilterRegistrationBean<WebStatFilter> filterRegistrationBean() { FilterRegistrationBean<WebStatFilter> 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)

解决方案:

  1. 检查@MapperScan的basePackages是否包含对应Mapper接口
  2. 检查setMapperLocations路径是否包含XML文件
  3. 确认XML中的namespace与Mapper接口全限定名一致

6.2 事务不生效

可能原因:

  1. 方法不是public
  2. 自调用(this.method())
  3. 异常被catch未抛出
  4. 数据库引擎不支持事务(如MyISAM)

6.3 连接泄漏

Druid监控面板查看:

  • activeCount持续增长
  • 检查代码中是否忘记关闭Connection/Statement/ResultSet

7. 性能优化建议

  1. 连接池参数调优:

    druid: min-idle: 5 max-active: 50 max-wait: 3000 time-between-eviction-runs-millis: 60000 min-evictable-idle-time-millis: 300000
  2. MyBatisPlus二级缓存:

    @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor()); interceptor.addInnerInterceptor(new CachingInnerInterceptor()); return interceptor; }
  3. SQL监控慢查询阈值:

    druid: filter: stat: log-slow-sql: true slow-sql-millis: 1000

8. 扩展思考

对于更复杂的多租户场景,可以考虑:

  1. 动态数据源路由(AbstractRoutingDataSource)
  2. Schema级别隔离
  3. MyBatisPlus租户插件

在K8s环境中部署时,建议:

  1. 使用ConfigMap管理数据源配置
  2. 为每个Pod设置合理的连接池大小
  3. 实现健康检查接口监控连接状态
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/22 7:22:52

[Released] 4DGS Unity插件——免费的4D高斯溅射实时渲染方案

4DGS细节大升级这是一款支持4D Gaussian Splatting动态资产的Unity实时渲染插件&#xff0c;兼容URP渲染管线&#xff0c;支持PC与主流Android VR一体机&#xff08;Pico、Quest系列&#xff09;&#xff0c;完全免费。 用这个插件能得到什么&#xff1f; 如果你正在评估这个插…

作者头像 李华
网站建设 2026/7/22 7:20:35

国际品牌在华战略调整与零售生态变革分析

1. 国际品牌在华战略调整的深层逻辑Guess这个美国牛仔服饰品牌最近宣布退出中国零售市场&#xff0c;背后反映的是国际品牌在中国市场面临的战略困境。作为从业十余年的零售行业观察者&#xff0c;我亲历过多个国际品牌在华战略调整的完整周期。Guess此次退出并非孤例&#xff…

作者头像 李华
网站建设 2026/7/22 7:19:08

告别“治而不愈”,中翰软件用AI给数据治理开了一剂“新药”

数据治理&#xff0c;为何总陷入“投入大、效果差”的死循环&#xff1f;中翰软件最新推出的AI原生解决方案&#xff0c;直击痛点。 传统治理有五大顽疾&#xff1a;技术思维主导&#xff0c;业务人员看不懂数据&#xff1b;管理与需求脱节&#xff0c;问题难定位&#xff1b;事…

作者头像 李华
网站建设 2026/7/22 7:18:36

Java企业级AI视频数字人解决方案:JBoltAI核心技术解析

1. 项目概述&#xff1a;JBoltAI视频数字人解决方案在当今企业内容创作领域&#xff0c;视频制作已成为品牌传播的核心手段&#xff0c;但传统视频制作面临三大痛点&#xff1a;人力成本高、制作周期长、内容同质化严重。JBoltAI视频数字人解决方案正是针对这些痛点设计的Java企…

作者头像 李华
网站建设 2026/7/22 7:17:34

C++策略模式实战:从算法封装到架构优化的设计模式指南

1. 项目概述&#xff1a;为什么策略模式是C开发者的“瑞士军刀”&#xff1f;在C的世界里&#xff0c;我们常常会遇到这样的场景&#xff1a;一个核心的业务逻辑&#xff0c;比如数据排序、支付计算或者图像渲染算法&#xff0c;随着需求迭代&#xff0c;未来可能会有多种不同的…

作者头像 李华
网站建设 2026/7/22 7:17:26

C++ Pimpl模式高级技巧:编译防火墙、二进制兼容与性能优化

1. 项目概述&#xff1a;为什么Pimpl模式是C大型项目的“定海神针”&#xff1f;如果你在维护一个超过十万行代码的C项目&#xff0c;每次修改一个头文件&#xff0c;哪怕只是加个私有成员变量&#xff0c;整个项目就得重新编译半小时&#xff0c;那感觉就像在泥潭里挣扎。编译…

作者头像 李华