芋道源码(无遮羞布版)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-starter | MyBatis-Plus 核心 |
dynamic-datasource-spring-boot-starter | 多数据源切换 |
druid-spring-boot-starter | Druid 连接池 |
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形成完整闭环。
七、总结:这套设计的三层思想
- 约定优于配置:
BaseDO定义通用字段约定,URL 定义数据库身份,IdType.NONE把选择权交给框架; - 启动期决策:数据库类型识别、ID 策略、Quartz 委托类全部在
EnvironmentPostProcessor阶段一次算清,运行时零开销; - 防御式扩展:自动填充只补空值、
limitN按方言降级、批量方法包装Db工具——处处给使用者留后路。
想继续深挖,推荐从这两个文件入手:
- 启动探测:IdTypeEnvironmentPostProcessor.java
- 实体基类:BaseDO.java
理解了它们,你就掌握了芋道源码(无遮羞布版) 数据访问层的骨架 🎯
【免费下载链接】ruoyi-spring-boot-all芋道源码(无遮羞布版)项目地址: https://gitcode.com/gh_mirrors/ru/ruoyi-spring-boot-all
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考