当前位置: 首页 > news >正文

MyBatis-Plus 通用 CRUD 实现原理技术文档

MyBatis-Plus 通用 CRUD 实现原理技术文档

版本:基于 MyBatis-Plus 3.5.5(JDK 17+)
面向:需要阅读源码、定制 BaseMapper、排查“魔法 SQL” 来源的开发人员


1 文档目标

  1. 说明 通用 CRUD(BaseMapper、IService) 在启动期如何 无 SQL 注入
  2. 拆解 SQL 模板 → BoundSql → JDBC 的完整链路
  3. 给出 自定义通用方法 的扩展点与示例

2 术语表

术语说明
TableInfoMyBatis-Plus 对表元数据的运行时封装(表名、主键、字段、填充器等)
SqlInjector将自定义方法模板注入到 Configuration 的策略接口
AbstractMethod一个通用 SQL 方法的最小单元(如 SelectById、Insert)
MapperBuilderAssistantMyBatis 原生助手,负责把 MappedStatement 注册到 Configuration

3 启动期注入流程

3.1 入口:MybatisPlusAutoConfiguration

@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {return new MybatisPlusInterceptor();   // 插件链
}
  • 自动配置类会读取 mybatis-plus.global-config.dbConfig.*,填充到 GlobalConfigDbConfig
  • 随后触发 MybatisConfiguration#addInterceptor()DefaultSqlInjector 注册为 Bean。

3.2 DefaultSqlInjector 的职责

public class DefaultSqlInjector extends AbstractSqlInjector {@Overridepublic List<AbstractMethod> getMethodList(Class<?> mapperClass) {return Stream.of(new Insert(),new DeleteById(),new UpdateById(),new SelectById(),...).collect(Collectors.toList());}
}
  • 每个 AbstractMethod 实现 两个核心方法
    • mappedStatement() 构建 MappedStatement
    • sqlMethod() 返回 String 模板(占位符由 TableInfo 填充)

3.3 模板 → MappedStatement

Insert 为例:

public class Insert extends AbstractMethod {@Overridepublic String sqlMethod(SqlMethod sqlMethod) {return "<script>INSERT INTO %s (%s) VALUES (%s)</script>";}@Overridepublic SqlCommandType sqlCommandType() {return SqlCommandType.INSERT;}@Overridepublic MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {String sql = String.format(sqlMethod(SqlMethod.INSERT_ONE),tableInfo.getTableName(),sqlSelectColumns(tableInfo, false),sqlInsertColumns(tableInfo, false, null));return addInsertMappedStatement(mapperClass, modelClass, sqlMethod(), sql);}
}
  • 占位符 %sTableInfo 动态替换 → 运行时无 XML
  • 最终通过 MapperBuilderAssistantMappedStatement 注册到 Configuration,ID = mapper接口全名 + “.” + methodName
    例如 com.demo.mapper.UserMapper.insert

4 运行期执行链路

4.1 调用栈

userMapper.insert(user)├─ MapperProxy.invoke()├─ MapperMethod.execute()├─ SqlSession.insert()├─ BaseExecutor.update()├─ SimpleExecutor.doUpdate()├─ PreparedStatementHandler.update()└─ JDBC PreparedStatement.execute()

4.2 SQL 模板填充

  • 占位符解析发生在 SqlSource#getBoundSql()
  • 字段过滤(逻辑删除、填充器)由 TableInfoParameterHandler 阶段完成
  • 乐观锁 会在 beforeUpdate() 中追加 version = version + 1

5 扩展:自定义通用方法

5.1 步骤

  1. 继承 AbstractMethod
  2. 注册到自定义 SqlInjector
  3. 在 Mapper 或 Service 层调用

5.2 实战:批量软删除

public class LogicDeleteBatchByIds extends AbstractMethod {@Overridepublic String sqlMethod(SqlMethod sqlMethod) {return "<script>UPDATE %s SET deleted = 1 WHERE id IN (%s)</script>";}@Overridepublic MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {String ids = "#{" + COLLECTION + "}";String sql = String.format(sqlMethod(SqlMethod.LOGIC_DELETE_BATCH_BY_IDS),tableInfo.getTableName(), ids);return addUpdateMappedStatement(mapperClass, modelClass, sqlMethod(), sql);}
}@Mapper
public interface UserMapper extends BaseMapper<User> {int logicDeleteBatchByIds(@Param("ids") List<Long> ids);
}

6 常见问题排查清单

现象排查命令可能原因
方法不存在Configuration#getMappedStatementIds未注册 SqlInjector
SQL 字段缺失打印 TableInfo#getAllInsertSqlColumn实体未加 @TableField
主键未回填检查 TableInfo#getKeyProperty实体主键未加 @TableId
逻辑删除失效查看 TableInfo#isLogicDelete全局配置未开启 logicDeleteField

7 结论

  • 通用 CRUD ≠ 魔法:启动期注入模板 + 运行期 TableInfo 填充
  • 可插拔:通过 SqlInjector/AbstractMethod 可在任意 Mapper 上追加新方法
  • 零侵入:不改变 MyBatis 原生执行链,便于与原生 XML 混合使用

深入 TableInfo 与 SqlInjector 源码,即可在团队内快速构建“私有通用方法库”,同时保持与 MyBatis-Plus 官方升级兼容。

http://www.dtcms.com/a/589984.html

相关文章:

  • 通俗易懂:YOLO模型原理详解,从零开始理解目标检测
  • 织梦 和wordpress建站seo是什么
  • GRNN广义回归神经网络分类预测+特征贡献SHAP分析+特征依赖图!Matlab
  • 深度学习周报(11.3~11.9)
  • 【MySQL】数据库基本知识
  • 连云港网站关键字优化如何网络营销环境分析包括哪些内容
  • 网站建设语言都有什么广东外贸网站推广
  • 临沂建网站公司网站切图是指什么
  • 不用写代码做网站软件飞狐小说网站建设
  • wdcp拒绝访问网站企业网站本身应该就是企业( )的一部分
  • 子数组|状态机dp
  • 家居网站建设如何自己公司网站维护
  • Spring Boot 3+Spring AI 打造旅游智能体!集成阿里云通义千问,多轮对话 + 搜索 + PDF 生成撑全流程
  • 西安网站设计制作一般多少钱新媒体营销的发展趋势
  • 手机T0智能算法交易个人开通指南
  • 卢沟桥网站建设互联网舆情报告
  • 4.2 Boost 库工具类 ignore_unused 的使用
  • 智能驾驶域控(ADCU)方案介绍
  • 关于我们的python日记本
  • 电子商城网站开发购物车网站联盟怎么做
  • 10、webgl 基本概念 + 坐标系统 + 立方体
  • 网站建设 类东莞网站建设方案外包
  • 小孩子和大人做的网站公司网站域名com好还是cn好
  • PostgreSQL 分区表实战:亿级订单表按时间拆分,查询提速 100 倍
  • 数字孪生如何落地
  • 4.1.8【2014统考真题】
  • 查询域名网站淮安淮阴网站建设
  • 智慧校园综合管理平台源码
  • 用Python识别图片中的文字(Tesseract OCR)
  • nvidia驱动安装(openEuler上安装T4驱动)