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

MyBatis-Plus——SQL注入器

MyBatis-Plus的SQL注入器其实是一种“扩展工具包”机制——当BaseMapper提供的默认方法(如selectById、deleteById)不够用时,我们可以通过它自定义通用方法,让所有Mapper接口都能直接使用。这里提供一个案例:自定义一个“删除表中所有数据”的deleteAll方法,用“工具箱”的比喻一步步拆解。

一、先理解核心需求:为什么需要自定义deleteAll?

MyBatis-Plus的BaseMapper虽然提供了很多基础方法,但没有“删除全表数据”的deleteAll方法(可能是为了安全,避免误操作)。如果多个表都需要“删除全表”功能,总不能在每个Mapper里重复写SQL吧?

这时候就需要SQL注入器:把deleteAll定义成“全局通用方法”,让所有继承BaseMapper的接口(比如StudentMapper、UserMapper)都能直接调用,不用重复开发。

二、逐步拆解:每个类的作用

1. 自定义方法类(DeleteAll):定义“具体工具”

// 注入方法类:相当于定义一个"删除全表"的工具
public class DeleteAll extends AbstractMethod {@Overridepublic MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {// 1. 定义要执行的SQL:delete from 表名(表名通过tableInfo获取,自动适配不同表)String sql = "delete from " + tableInfo.getTableName();// 2. 定义方法名:和Mapper接口中声明的方法名一致(这里是deleteAll)String method = "deleteAll";// 3. 构建SqlSource:MyBatis中用于传递SQL的对象SqlSource sqlSource = this.languageDriver.createSqlSource(this.configuration, sql, modelClass);// 4. 构建删除类型的MappedStatement(MyBatis执行SQL的核心对象)return this.addDeleteMappedStatement(mapperClass, method, sqlSource);}
}

作用:这是“具体工具的设计图”,定义了deleteAll方法要执行的SQL(删除全表)、方法名,以及如何生成MyBatis能识别的执行对象(MappedStatement)。

继承AbstractMethod的原因:MyBatis-Plus通过AbstractMethod统一管理方法生成逻辑,我们只需按照它的规范实现即可。

2. SQL注入器(MySqlInject):将“工具”放入“公共工具箱”

// SQL自动注入器:相当于把自定义工具放到所有Mapper都能访问的公共工具箱
@Component
public class MySqlInject extends AbstractSqlInjector {@Overridepublic List<AbstractMethod> getMethodList(Class<?> mapperClass, TableInfo tableInfo) {List<AbstractMethod> methods = new ArrayList<>();// 把自定义的DeleteAll方法添加到方法列表中methods.add(new DeleteAll()); return methods;}
}

作用:注入器的职责是“收集所有自定义方法”,并在MyBatis-Plus启动时,将这些方法注入到所有继承BaseMapper的接口中。

简单说:没有注入器,DeleteAll方法只是一个孤立的类;有了注入器,它会告诉MyBatis-Plus:“把deleteAll方法加到所有Mapper里,让它们都能用”。

3. 在Mapper接口中声明方法:“告诉工具箱要用这个工具”

// StudentMapper:具体的工具箱,继承BaseMapper后,自动获得基础工具+注入的自定义工具
public interface StudentMapper extends BaseMapper<Student> {// 声明deleteAll方法(无需实现,因为注入器已经帮我们生成了实现)void deleteAll();
}

为什么只声明不实现?
因为DeleteAll类已经通过注入器生成了对应的SQL和执行逻辑,这里只是“告诉MyBatis:我要用这个方法”,实际执行时会找到注入器生成的实现。

4. 注销BlockAttackInnerInterceptor插件:“暂时关闭安全锁”

@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));// 注释掉防全表删除插件:因为deleteAll就是全表删除,会被它拦截// interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor()); interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());return interceptor;
}

原因:BlockAttackInnerInterceptor是MyBatis-Plus的“安全插件”,会拦截全表删除/更新(防止误操作)。而我们的deleteAll就是要全表删除,所以需要暂时注释掉,否则会执行失败。

5. 测试方法:“使用工具”

@Test
public void testDeleteAll() {// 直接调用StudentMapper中的deleteAll方法studentMapper.deleteAll();
}

此时调用的deleteAll,就是我们通过注入器自定义的全表删除方法。

三、完整执行流程:从启动到调用

用“工具箱准备→使用工具”的流程理解:

  1. 启动阶段:准备工具箱

    • 项目启动时,Spring会加载MySqlInject(因为加了@Component);
    • MySqlInject的getMethodList方法被调用,返回包含DeleteAll的方法列表;
    • MyBatis-Plus会根据这些方法,为所有继承BaseMapper的接口(如StudentMapper)生成对应的实现逻辑(即MappedStatement,包含SQL和执行方式);
    • 最终,StudentMapper不仅有BaseMapper的默认方法,还多了deleteAll方法。
  2. 调用阶段:使用工具

    • 执行studentMapper.deleteAll()时,MyBatis会找到注入器生成的MappedStatement;
    • 执行其中定义的SQL:delete from student(表名由TableInfo自动获取,对应Student实体类的表);
    • 数据库执行全表删除,完成操作。

四、总结

SQL注入器就像“全局工具注册中心”:

  • 自定义方法类(DeleteAll)是“工具的设计图”,定义了工具的功能(执行什么SQL);
  • 注入器(MySqlInject)是“工具管理员”,把工具分发到所有Mapper的“工具箱”里;
  • Mapper接口声明方法是“告诉管理员要用这个工具”;
  • 最终,我们可以在任何Mapper中直接使用这个工具(调用方法)。

这种机制的好处是:一次定义,到处使用,避免重复开发通用方法。

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

相关文章:

  • 华清远见25072班C语言学习day7
  • 《算法导论》第 21 章-用于不相交集合的数据结构
  • 01-Ansible 自动化介绍与使用
  • 【数据结构】二叉树结构与相关实现
  • .NET MAUI框架编译Android应用流程
  • 服务降级方式
  • Python实现Amazon Redshift数据库元数据提取类
  • 分布式事务Seata使用不当引发的全局锁问题
  • 解锁Java线程池:从原理到实战的深度剖析
  • 无人机三维路径规划
  • 前端基础知识NodeJS系列 - 06( Node 中的 Stream 的理解?应用场景?)
  • 如何实现PostgreSQL的高可用性,包括主流的复制方案、负载均衡方法以及故障转移流程?
  • TensorBoard的使用 小土堆pytorch记录
  • 数据类型 list
  • 小白挑战一周上架元服务——ArkUI04
  • 前端最新Vue2+Vue3基础入门到实战项目全套教程,自学前端vue就选黑马程序员,一套全通关!笔记
  • Java面试宝典:G1垃圾收集器上
  • 超详细!VMware12 安装win7操作系统
  • react+vite来优化下每次使用hook函数都要引入的情况
  • Neo4j Cypher
  • 哪个视频播放器好用?视频播放器PotPlayer下载安装与调教教程
  • QGraphicsAnchorLayout测试pyside6和C++
  • 微内核与插件化设计思想及其在前端项目中的应用
  • 怎么写好汉语言文学专业的论文?
  • TongSearch3.0.6.0安装和使用指引(by lqw)
  • Day 38: Dataset类和DataLoader类
  • 三点估算法(Three-Point Estimation)
  • OpenHarmony介绍
  • 知识篇 | Oracle Active Data Guard(ADG)同步机制再学习
  • TCP服务器网络编程设计流程详解