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

mybatis-plus从入门到入土(四):持久层接口之BaseMapper和选装件

大家好,今天继续更新MybatisPlus从入门到入土系列,上一次的持久层接口还没讲完,只讲了IService接口,今天我们继续来讲一下。

BaseMapper

BaseMapper中的方法也比较简单,都是增删改查的基础API,不知道大家还有没有印象,上次在讲IService相关类结构的时候,我们分析了一个CrudRepository,它就是通过成员变量BaseMapper完成了部门能力,当时我还把BaseMapper比喻成引擎(或者发动机)。BaseMapper的相关类结构只有一个父接口MapperMapper接口作为顶层接口,只起到标记的作用,没有定义方法。因此BaseMapper的相关类结构是非常清晰的,这里也不过多赘述了。关于BaseMapper的实现原理,我们计划在后面讲解源码的时候会讲到。

Mapper层选装件

关于Mapper层选装件,其实就是Mapper的扩展功能,虽然MybatisPlus已经提供了BaseMapper这个比较丰富的父类,但是还是有些比较场景化的需求需要定制实现,这就是选装件的意义。在官方文档中描述也可以看出,选装件是需要配合SQL注入器一起使用的。关于SQL注入器后面还会单独说到,这些选装件都位于com.baomidou.mybatisplus.extension.injector.methods,下面我们具体来看下这几个选装件。

在这里插入图片描述
关于这几个选装件的作用,大家可以看下官方文档https://baomidou.com/guides/data-interface/#mapper-%E5%B1%82%E9%80%89%E8%A3%85%E4%BB%B6,我们主要分析下他们的具体实现。还有一点需要补充的是,关于SQL注入器后面会讲到,今天只对这几个选装件做一下剖析。

首先在3.5.12版本中能看到的选装件有5个:AlwaysUpdateSomeColumnByIdInsertBatchSomeColumnLogicDeleteBatchByIdsLogicDeleteByIdWithFillUpsert。其中LogicDeleteBatchByIdsLogicDeleteByIdWithFill官方已标注为过期。

AbstractMethod

首先说下他们都继承的类,就是这个AbstractMethodAbstractMethod作为SQL注入的基础类,它的主要方法是inject方法。

TIPS

这里说一个小技巧啊,当你看源码的时候,仅从类出发不知道入口点是哪个方法,可以先找下类中public的方法,一般需要子类实现的都会标注为protected。

/*** 注入自定义方法*/
public void inject(MapperBuilderAssistant builderAssistant, Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {this.configuration = builderAssistant.getConfiguration();this.builderAssistant = builderAssistant;this.languageDriver = configuration.getDefaultScriptingLanguageInstance();/* 注入自定义方法 */injectMappedStatement(mapperClass, modelClass, tableInfo);
}

再看下injectMappedStatement方法。injectMappedStatement是一个抽象方法,实现的子类就包括我们提到的那几个选装件。
在这里插入图片描述
我们挑一个看下吧,比如AlwaysUpdateSomeColumnById,看下这个类中的injectMappedStatement是怎么实现的。

@Override
public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {SqlMethod sqlMethod = SqlMethod.UPDATE_BY_ID;final String additional = optlockVersion(tableInfo) + tableInfo.getLogicDeleteSql(true, true);String sqlSet = this.filterTableFieldInfo(tableInfo.getFieldList(), getPredicate(),i -> i.getSqlSet(true, ENTITY_DOT), NEWLINE);sqlSet = SqlScriptUtils.convertSet(sqlSet);String sql = String.format(sqlMethod.getSql(), tableInfo.getTableName(), sqlSet,tableInfo.getKeyColumn(), ENTITY_DOT + tableInfo.getKeyProperty(), additional);SqlSource sqlSource = super.createSqlSource(configuration, sql, modelClass);return addUpdateMappedStatement(mapperClass, modelClass, methodName, sqlSource);
}

这个方法的主要作用就是创建一个updateMappeedStatement,加入到Mybatis的全局配置中。其中sqlMethod是SQL语句的模板,拿到这个UPDATE_BY_ID的sql语句模板后,下面就是把模板填充成正常的SQL语句,就涉及到需要set的字段啊,乐观锁之类的。当这些信息都拼接完了,把它放入一个SqlSource的对象中,然后根据这个SqlSource对象生成MappedStatement。整个方法逻辑看起来比较清晰,但是有几点需要补充一下,如果没有这些前置知识,这块可能还是比较蒙。

  • SqlMethod长什么样?

    我们看下这个SqlMethod究竟长什么样,其实就是一个String模板,也就是我们经常用的String.format的定义形式。而<script>标签是Mybatis提供的,该标签主要是用来拼接SQL脚本的。

    UPDATE_BY_ID("updateById", "根据ID 选择修改数据", "<script>\nUPDATE %s %s WHERE %s=#{%s} %s\n</script>")
    
  • MappedStatement类是干什么的?

    这个类是Mybatis框架中的重要类,他对应的就是xml文件中的一个个标签包起来的元素,比如<insert>元素,<select>元素。这里简述一下Mybatis的原理啊,Mybatis框架启动的时候会去解析xml文件,将里面的一个个标签实例化成一个个MappedStatement对象。最终这些解析出来的MappedStatement都会放入Configuration类,关于这一块大家可以看下org.apache.ibatis.builder.xml.XMLConfigBuilder#parseConfiguration

  • SqlSource类是干什么的?

    其实从类的注释中,我们基本上也能明白是什么意思了,就是在<insert>标签中的插入语句,包在<select>语句中的查询语句等,这个SqlSource类的作用就是这些SQL语句的容器。

    /*** Represents the content of a mapped statement read from an XML file or an annotation. It creates the SQL that will be passed to the database out of the input parameter received from the user.* 表示从 XML 文件或注释读取的映射语句的内容。它创建将从用户收到的输入参数传递到数据库的 SQL。* @author Clinton Begin*/
    public interface SqlSource {BoundSql getBoundSql(Object parameterObject);}
    

经过上面的几个问题,大家应该知道了这几个类其实就是定义了几个不同的MappedStatement方法,然后注入到Configuration类中。相比于传统的在xml中定义,或者在mapper方法上面注解定义,这些都是自己注入的,关于怎么注入的,在哪注入的,这块就是SQL注入器的内容了,我们后面会讲到。

好了,今天先讲到这里。这里需要说明一下,官方文档中持久化接口涉及的东西很多,我们可能得分多次讲解,我最初规划的是一篇讲完的,但我还是觉得一次讲太多会很长,也不太好消化,就篇幅短一些吧。下周见,拜拜。

先讲到这里。这里需要说明一下,官方文档中持久化接口涉及的东西很多,我们可能得分多次讲解,我最初规划的是一篇讲完的,但我还是觉得一次讲太多会很长,也不太好消化,就篇幅短一些吧。下周见,拜拜。

http://www.lryc.cn/news/608992.html

相关文章:

  • MySQL极简安装挑战
  • nmon使用教程
  • sqli-labs:Less-23关卡详细解析
  • 基于Python实现生产者—消费者分布式消息队列:构建高可用异步通信系统
  • cpy相关函数区分
  • Ollama模型库模型下载慢完美解决(全平台)
  • 设计模式 - 组合模式:用树形结构处理对象之间的复杂关系
  • 新手向:Python制作贪吃蛇游戏(Pygame)
  • FLUX.1 Krea - 告别“AI味”,感受超自然细节,黑森林最新开源文生图模型 支持50系显卡 一键整合包下载
  • 控制建模matlab练习08:根轨迹
  • js--2048小游戏
  • 【openlayers框架学习】十:openlayers中控件的使用
  • Ubuntu系统VScode实现opencv(c++)视频的处理与保存
  • C语言与数据结构:从基础到实战
  • 解决飞书文档中PDF文档禁止下载的问题
  • Linux 环境下 Docker 安装与简单使用指南
  • ubuntu syslog中appindicator报错解决
  • 扩散模型(一)——综述
  • Rust: 获取 MAC 地址方法大全
  • 【MySQL进阶】------MySQL程序
  • 机器学习第三课之逻辑回归(三)LogisticRegression
  • 2025H1具身智能产业十大数据
  • Python训练营打卡 Day27
  • 【网络安全】日志文件格式
  • Linux 系统调用 stat 完全用例
  • Web前端文件上传安全与敏感数据安全处理
  • HiveMQ核心架构思维导图2024.9(Community Edition)
  • 反向代理+网关部署架构
  • 动态置信度调优实战:YOLOv11多目标追踪精度跃迁方案(附完整代码)
  • 关于corn