1884 字
约 6 分钟
3
多数据源(MyBatis)入门

多数据源(MyBatis)入门

1. 一句话简介

多数据源是指一个应用同时连接并操作多个数据库(如一个主库 master 和一个从库 slave),并按需在不同库之间切换访问的能力。本模块所演示的是基于苞米豆(baomidou)团队的 dynamic-datasource-spring-boot-starter + MyBatis-Plus 实现的方案:只需在 application.yml 中声明多个数据源,再在 Service 上打一个 @DS 注解即可完成数据源切换,框架底层通过 AOP 拦截在方法执行前后动态路由到目标库。

其核心价值在于解决「一个业务系统同时访问多个数据库」的问题——尤其是读写分离和分库访问这两种最常见的诉求,同时把传统方案中需要手写多套 DataSourceSqlSessionFactoryTransactionManager 的繁琐配置彻底简化。

2. 什么时候使用

✅ 适用场景:

  • 读写分离:MySQL 主从复制架构下,写操作走主库、读操作走从库,通过类级别 @DS("slave") + 方法级别 @DS("master") 即可优雅路由,这正是本 demo 的核心演示逻辑(addUser 写主库,list 读从库)。
  • 多库按业务隔离:不同业务模块使用不同的数据库,同一应用中按 Service 或方法粒度访问不同库,避免把所有表堆在同一个库里。
  • 追求低成本接入:团队已采用 MyBatis-Plus,希望数据源切换尽量少写样板代码——纯注解驱动,无需业务代码感知数据源实现细节。
  • 需要灵活切换、动态路由:路由规则可能随时间变化,希望用注解在方法粒度精确控制,而非靠包路径这类编译期绑定的方式。

❌ 不适用 / 需谨慎:

  • 跨库强一致事务@DS 本质是路由不同的物理连接,跨数据源的分布式事务需要额外引入 Seata、XA 等方案,否则无法保证 ACID。若业务强依赖跨库事务,单库或多数据源 + 分布式事务方案更合适。
  • 数据真正需要跨库关联查询:多数据源的多个库之间无法用一条 SQL 做 JOIN,需在应用层分别查询再合并,性能与开发成本都会上升。此时应考虑分库分表中间件(如 ShardingSphere)或合并为单库。
  • 需要复杂路由策略:若路由依赖用户身份、租户、请求参数等运行时上下文做动态决策,纯注解模式的扩展性有限,需要扩展自定义切面或改用分库分表组件。
  • 已用 JPA/其他 ORM 且仅需完全隔离的多库:若只是「几个独立库之间互不切换」,包路径隔离式的 JPA 方案或独立配置也足够,不一定需要动态数据源框架。

3. 常见业务场景

MySQL 主从读写分离:这是最经典的应用。生产环境搭建 MySQL 主从复制后,将写操作(INSERT/UPDATE/DELETE)路由到 master 主库、查询操作路由到 slave 从库,有效分担主库读压力。如本 demo,UserServiceImpl 类上 @DS("slave")listsave 默认走从库,仅对有写需求的 addUser 方法标注 @DS("master"),实现读写分离而无需改动业务 SQL。

多租户/多业务数据库隔离:中后台系统把用户服务、订单服务、日志服务拆到不同数据库,甚至每个租户拥有独立库。通过 @DS 在每个 Service 上指定对应库别名,即可在同一应用内按业务组织数据,避免大量表耦合在单个库影响性能与运维。

报表与分析类只读库:把高频交易的业务库与低频的分析报表库分离,报表相关 Mapper 统一路由到只读的从库或数仓,查询不阻塞主库写入,同时通过 master/slave 别名区分两类连接。

灰度/多环境数据源切流:同一套代码在切换不同数据源时只需修改 application.yml 或通过配置中心的别名映射,配合 @DS 注解即可在开发、测试、生产或新旧库之间快速切换,便于平滑迁移。

系统解耦下的共享数据访问:多个子系统共享一套基础数据(用户、配置),但各自连接的主库节点不同,通过动态数据源让同一份服务代码按落地环境路由到对应的基础库。

4. 同类技术对比

对比维度 dynamic-datasource + MyBatis-Plus(本模块) 原生 MyBatis 多数据源 Spring Data JPA 多数据源 ShardingSphere-JDBC(分库分表/读写分离)
数据源切换方式 @DS 注解,方法/类粒度,运行时动态 手写多套 DataSource/SqlSessionFactory,包路径隔离 编译期固定,靠 @Primary + 多 repo 包划分 配置规则 + 内置负载均衡策略,SQL 级自动路由
配置复杂度 低(YAML + 注解) 高(多套 Bean 与事务管理器) 高(多 EntityManagerFactory/TransactionManager 中(需理解分片/读写规则配置)
读写分离支持 支持,注解显式指定主从 支持,需自行维护 支持,但需额外 workaround 内置读写分离 + 负载均衡,开箱即用
分布式/跨库能力 弱(仅动态路由,跨库事务需外部组件) 强(分片、广播表、跨库查询 SQL 解析)
关联查询能力 不支持跨库 JOIN 不支持 不支持 支持一定范围的分片内 JOIN
学习成本 低,围绕 MyBatis-Plus 生态 中,需理解多套 Bean 管理 中,需理解 JPA 多 EntityManager 高,概念多(分片键、绑定表、广播表)
适用规模 中小规模,主从 + 少量业务多库 需要细粒度手控的小场景 JPA 阵营的多库隔离 中大规模,数据量大、需横向拆分的场景
事务管理 由框架协调单库事务,跨库不保证 每套数据源独立事务管理器 每套数据源独立事务管理器 提供分布式事务扩展(Seata/XA)

选型建议:

  • 团队深度使用 MyBatis-Plus、需要「注解级」简单切换的读写分离或多库访问:优先 dynamic-datasource-spring-boot-starter。接入成本最低,与 MyBatis-Plus 无缝集成,适合绝大多数中小型业务。
  • 数据量持续增长、需要真正的分片/水平拆分、或要跨库聚合查询:应选择 ShardingSphere-JDBC 这类分库分表中间件,动态数据源只解决「路由」不解决「分片」,此时能力已不够。
  • 技术栈偏 JPA/Repository 风格,且各库完全独立、互不切换:使用原生 JPA 多数据源即可,避免为简单需求引入框架依赖。
  • 需要底层的完全掌控,或依赖极少数特定 Mapper 的行为定制:原生 MyBatis 多 SqlSessionFactory 方案更直接,但需接受更高的配置复杂度和潜在的事务协调成本。
多数据源(MyBatis)入门
http://clxhxhhr.top/posts/516/
作者
clxstart
发布于
2026-09-07
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。