☰
芋道源码(无遮羞布版)MyBatis-Plus Starter源码深潜:多数据库适配、逻辑删除与智能ID策略
2026/10/9 18:45:03 网站建设 项目流程

芋道源码(无遮羞布版)MyBatis-Plus Starter源码深潜:多数据库适配、逻辑删除与智能ID策略

【免费下载链接】ruoyi-spring-boot-all芋道源码(无遮羞布版)项目地址: https://gitcode.com/gh_mirrors/ru/ruoyi-spring-boot-all

芋道源码(无遮羞布版) 中的MyBatis-Plus Starter(yudao-spring-boot-starter-mybatis)是整套框架的"数据底座":仅引入一个依赖,就多数据库适配、逻辑删除、智能 ID 策略、字段自动填充等能力全部就位。本文带你用 10 分钟读懂它的核心源码设计 🚀

一、先鸟瞰:一个 Starter 打包了哪些能力

模块的 pom.xml 自述为"数据库连接池、多数据源、事务、MyBatis 拓展",关键依赖一览:

依赖作用
mybatis-plus-boot-starterMyBatis-Plus 核心
dynamic-datasource-spring-boot-starter多数据源切换
druid-spring-boot-starterDruid 连接池
mybatis-plus-join-boot-starter连表 Join 查询
easy-trans-*VO 数据字段翻译
ojdbc8、postgresql、mssql-jdbc、DmJdbcDriver18(均optional)多数据库驱动,按需生效

源码结构清晰分为四块,建议对照目录阅读:

yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/ ├── datasource/ # 数据源配置(Druid 监控广告过滤等) ├── mybatis/ │ ├── config/ # 自动配置 + 启动期环境处理器 │ ├── core/ # BaseDO、BaseMapperX、查询包装器、TypeHandler │ └── translate/# 字段翻译

二、多数据库适配:一条 URL 如何"告诉"系统自己是谁?

这是本 Starter 最精巧的设计。核心是启动期环境处理器 IdTypeEnvironmentPostProcessor.java,它通过META-INF/spring.factories在 Spring 容器刷新之前执行,做三件事:

2.1 从 JDBC URL 自动识别数据库类型

它读取spring.datasource.dynamic.primary主数据源的连接 URL,交给 JdbcUtils.java 解析——底层复用 Druid 的 URL 解析能力,把jdbc:mysql://…、jdbc:oracle:thin:@…等统一映射为 MyBatis-Plus 的DbType枚举,并存入 SqlConstants.java 供运行时使用。

2.2 让不同数据库的"取 N 条"语法正确

不同数据库限制返回行数的方式差异很大。增强包装器 QueryWrapperX.java 的limitN方法就是靠上面识别出的DbType做分发:

  • Oracle / Oracle12c→ROWNUM <= n
  • SQL Server→SELECT TOP n *
  • 其他(MySQL、PostgreSQL 等)→LIMIT n

业务代码只需wrapper.limitN(1),无需关心底层方言。

2.3 按数据库选择序列主键生成器

当配置id-type=INPUT(依赖数据库自生成 ID,如序列)时,YudaoMybatisAutoConfiguration.java 会按DbType返回对应的IKeyGenerator:PostgreSQL、Oracle(含 12C)、H2、人大金仓、达梦各有专属实现,找不到则直接抛异常快速失败。

💡 小贴士:同一个 PostProcessor 还会顺手为 Quartz 设置对应的jobStore.driverDelegateClass(如PostgreSQLDelegate、OracleDelegate),定时任务同样"零配置"适配多库。

三、逻辑删除:BaseDO 一行注解搞定

所有实体几乎都继承抽象基类 BaseDO.java,它定义了 5 个通用字段:

字段注解说明
createTime@TableField(fill = INSERT)创建时间,插入时自动填充
updateTime@TableField(fill = INSERT_UPDATE)更新时间,插入+更新时填充
creator@TableField(fill = INSERT)创建人(String,预留非数值拓展)
updater@TableField(fill = INSERT_UPDATE)更新人
deleted@TableLogic逻辑删除标记

@TableLogic是逻辑删除的核心:MyBatis-Plus 会把DELETE语句改写成UPDATE … SET deleted = 1,并自动在所有SELECT中追加deleted = 0条件。业务层执行"删除"后数据仍在表中,既满足审计与合规要求,又保留了误删恢复的可能 ✅

四、智能 ID 策略:配置 NONE 就是"帮我做主"

MyBatis-Plus 的IdType.NONE本身含义是"由 MP 自动决定"。启动期处理器把这件事做实了,规则非常直观:

  • 情况一:库属于 Oracle、PostgreSQL、人大金仓、DB2、H2 → 设为IdType.INPUT(由应用/序列输入主键);
  • 情况二:其余库(如 MySQL)→ 设为IdType.AUTO(数据库自增)。

也就是说,迁移数据库时连id-type配置都不用改,URL 一变,策略自动跟随。当然,你始终可以在application.yaml中显式指定mybatis-plus.global-config.db-config.id-type覆盖默认行为——显式配置永远优先。

五、字段自动填充:谁在什么时候改了数据?

填充逻辑在 DefaultDBFieldHandler.java 中实现,注册为 MyBatis-Plus 的MetaObjectHandler:

  • insertFill:createTime/updateTime为空时补当前时间;creator/updater为空时取当前登录用户 ID(通过WebFrameworkUtils.getLoginUserId());
  • updateFill:同理补充updateTime与updater。

所有"已有值不覆盖"的防御式判断,让手动赋值与自动填充可以安全共存——这为单元测试和批量导入留足了口子。

六、查询体验增强:BaseMapperX 与类型处理器

6.1 一页顶十页的 BaseMapperX

BaseMapperX.java 继承 MyBatis-Plus-Join 的MPJBaseMapper,用 default 方法补齐了高频 CRUD:

  • selectPage(PageParam, wrapper):分页查询直接返回统一PageResult,且支持pageSize=-1时不分页查全量;排序字段由 MyBatisUtils.java 的buildPage统一构建;
  • selectJoinPage:连表分页查询,配合MPJLambdaWrapperX使用;
  • selectOne/selectCount/selectList的多参数重载:selectOne(UserDO::getMobile, "138…")一行搞定;
  • insertBatch/updateBatch/insertOrUpdate:批量操作直接委托Db工具类。

6.2 类型处理器:把复杂类型塞进 varchar

core/type目录提供了一组开箱即用的TypeHandler:

  • LongListTypeHandler.java(及IntegerListTypeHandler、StringListTypeHandler):List↔ 逗号分隔字符串;
  • EncryptTypeHandler.java:基于 AES 的字段级加密,密钥来自mybatis-plus.encryptor.password,敏感字段落库即密文 🔐

6.3 分页插件

自动配置类 中注册的MybatisPlusInterceptor内挂了PaginationInnerInterceptor,这是 MP 3.4+ 的标准分页写法,配合BaseMapperX.selectPage形成完整闭环。

七、总结:这套设计的三层思想

  1. 约定优于配置:BaseDO定义通用字段约定,URL 定义数据库身份,IdType.NONE把选择权交给框架;
  2. 启动期决策:数据库类型识别、ID 策略、Quartz 委托类全部在EnvironmentPostProcessor阶段一次算清,运行时零开销;
  3. 防御式扩展:自动填充只补空值、limitN按方言降级、批量方法包装Db工具——处处给使用者留后路。

想继续深挖,推荐从这两个文件入手:

  • 启动探测:IdTypeEnvironmentPostProcessor.java
  • 实体基类:BaseDO.java

理解了它们,你就掌握了芋道源码(无遮羞布版) 数据访问层的骨架 🎯

【免费下载链接】ruoyi-spring-boot-all芋道源码(无遮羞布版)项目地址: https://gitcode.com/gh_mirrors/ru/ruoyi-spring-boot-all

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询