当前位置: 代码网 > it编程>编程语言>Java > Mybatis数据源切换的几种方法小结

Mybatis数据源切换的几种方法小结

2026年07月21日 Java 我要评论
方案一:配置文件 + 硬编码切换(基础版)你提到的第一种方式,是最基础、最直观的实现。它的核心流程是:配置:在 application.yml 或 mybatis-config.xml 中定义多个数据

方案一:配置文件 + 硬编码切换(基础版)

你提到的第一种方式,是最基础、最直观的实现。它的核心流程是:

  1. 配置:在 application.yml 或 mybatis-config.xml 中定义多个数据源(如 master, slave1, slave2)。
  2. 持有:在代码中通过一个工具类(比如使用 threadlocal)持有当前线程要使用的数据源 key。
  3. 切换:在业务代码中,手动调用工具类的方法(如 datasourcecontextholder.setdatasource("slave1"))来切换。
维度评价
优点简单直接,容易理解,没有黑盒。适合业务逻辑简单、数据源切换点非常明确的场景。
缺点切换逻辑和业务代码耦合,侵入性强。如果忘记在方法结束时清除上下文,可能导致后续逻辑使用了错误的数据源,产生难以追踪的 bug。

方案二:aop 切面编程(解耦版)

这是对方案一的优化,也是目前最常用的实践。它通过 spring aop 将“切换”这个动作从业务代码中抽离出来。

核心逻辑是:定义一个注解(如 @datasource("slave1")),然后编写一个切面,拦截所有带有该注解的方法,在方法执行前解析注解并将数据源标识设置到 threadlocal 中,方法执行后在 @after 中清除标识。

维度评价
优点切换逻辑与业务解耦,代码更干净。只需在类或方法上加一个注解就能切换,可维护性高,是生产环境最推荐的实现方式。
缺点需要编写切面类和注解,有一定学习成本。对 aop 的作用范围(如 @transactional 的优先级)需要特别注意,避免事务开启后再切换数据源导致切换失效。

方案三:继承abstractroutingdatasource(动态路由版)

这是 spring 提供的官方扩展点,也是实现方案一和方案二的底层基石。

abstractroutingdatasource 本身是一个数据源,它内部管理着一个 map<object, object> 来存放真实数据源,并根据 determinecurrentlookupkey() 方法返回的 key 来决定路由到哪个真实数据源。我们只需要实现这个方法来返回我们通过 threadlocal 设置的 key 即可。

很多资料和第三方库(包括 mybatis-plus 的 dynamic-datasource)的底层,本质上都是对 abstractroutingdatasource 的封装和增强。

方案四:使用第三方库(成熟版)

你提到的 druid(数据库连接池)和 hikaricp(连接池),它们本身并不直接提供数据源切换功能,但它们是这个方案中不可或缺的“高性能连接池”组件。

真正用于动态切换数据源的明星第三方库,是 mybatis-plus 生态下的 dynamic-datasource。

维度评价
优点开箱即用,功能强大。支持数据源分组、密码解密、多主多从、敏感信息加密、集成 seata 分布式事务等。只需引入依赖并在 application.yml 中配置,然后直接在方法上使用 @ds("slave1") 注解即可。
缺点引入了一个外部依赖。如果项目没有使用 mybatis-plus,需要额外集成。对于非常简单的需求,可能显得有点“重”。

📊 最终选择指南

你的情况推荐方案
项目简单,切换点极少(1-2个),且未来不会扩展方案一(硬编码)即可。
标准企业级应用,使用 spring boot + mybatis方案二(自研 aop + abstractroutingdatasource) 是主流选择,平衡了灵活性与可控性。
已经使用 mybatis-plus,或希望最大程度简化配置方案四(dynamic-datasource 插件) 是最高效的选择。
有非常复杂的动态路由规则(如根据 userid 哈希取模)方案三(继承 abstractroutingdatasource) 是最灵活、最底层的方式,可以在 determinecurrentlookupkey() 中实现任意逻辑。

对于大多数项目,方案二(aop + 注解 + abstractroutingdatasource) 和 方案四(mybatis-plus 的 dynamic-datasource) 是最值得考虑的。

另外补充一点,无论选择哪种方案,都要注意:如果在 spring 事务(@transactional)中切换数据源,必须在事务开启之前进行。因为事务管理器在开启时就已经确定了要使用的数据源,之后的切换将不会生效。如果需要在事务中切换数据源,可以考虑使用 @transactional(propagation = propagation.requires_new) 开启一个新的事务,或将切换逻辑放在一个没有事务的方法中调用。

到此这篇关于mybatis数据源切换的几种方法小结的文章就介绍到这了,更多相关mybatis数据源切换内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com