news 2026/5/1 11:45:09

Spring boot 4 搞懂MyBatis-Plus的用法

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Spring boot 4 搞懂MyBatis-Plus的用法

MyBatis-Plus 是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生

官方地址:
git源码
文档

Spring boot 4如何集成

增加依赖

Add MyBatis-Plus dependency

<mybatisplus.version>3.5.15</mybatisplus.version><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-spring-boot4-starter</artifactId><version>${mybatisplus.version}</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-jsqlparser</artifactId><version>${mybatisplus.version}</version></dependency>

配置

@ConfigurationpublicclassMybatisPlusConfig{@BeanpublicMybatisPlusInterceptormybatisPlusInterceptor(){MybatisPlusInterceptormybatisPlusInterceptor=newMybatisPlusInterceptor();// 数据权限mybatisPlusInterceptor.addInnerInterceptor(newDataFilterInterceptor());// 分页插件mybatisPlusInterceptor.addInnerInterceptor(newPaginationInnerInterceptor());// 乐观锁mybatisPlusInterceptor.addInnerInterceptor(newOptimisticLockerInnerInterceptor());// 防止全表更新与删除mybatisPlusInterceptor.addInnerInterceptor(newBlockAttackInnerInterceptor());returnmybatisPlusInterceptor;}}

基础特性

  1. “零SQL” CRUD
    • 核心点:业务模块的Mapper 接口继承BaseMapper<T>,即可拥有insertselectByIdupdateByIddeleteBatchIds等 17 个常用方法。
    • Service CRUD:除了 Mapper 层,MP 还提供了IServiceServiceImpl,封装了更多的业务逻辑方法(如saveBatch批量插入)。
    • 提供SqlHelper工具类实现批量写入或更新操作
  2. 条件构造器(Wrapper)
    • 三板斧QueryWrapper(用于查询,支持lambda避免字段名写错)、UpdateWrapper(用于更新,支持链式设置 set 值)。
    • Lambda 表达式:推荐使用LambdaQueryWrapper,利用方法引用(如User::getName)来指定字段,编译期检查,防止 SQL 拼写错误。
  3. 常用注解
    • @TableName:指定表名(如果类名与表名不一致)。
    • @TableId:指定主键策略(如IdType.AUTO自增,IdType.ASSIGN_ID雪花算法)。
    • @TableField:填充字段(如创建时间、更新时间自动填充FieldFill.INSERT_UPDATE),或者逻辑删除字段@TableLogic

增强功能

  1. 自动填充
    • 自动填充:实现MetaObjectHandler接口,重写insertFillupdateFill方法,统一处理create_timeupdate_time等字段。
  • 逻辑删除:配置后,delete语句会自动转化为UPDATE语句(设置删除标记),查询时自动追加WHERE deleted = 0条件。 【在实体类中,对应数据库表的逻辑删除字段上添加@TableLogic注解】
    • 插入:逻辑删除字段的值不受限制。
    • 查找:自动添加条件,过滤掉标记为已删除的记录。
    • 更新:防止更新已删除的记录。
    • 删除:将删除操作转换为更新操作,标记记录为已删除
  • 自定义ID生成器
    • IdentifierGenerator主要用于生成数据库表的主键ID
    • KeyGenerator是MyBatis框架中的一个接口,用于在执行SQL语句时生成键值,通常用于生成自增主键或者在执行INSERT语句后获取新生成的ID
    • MyBatis-Plus 内置支持多种数据库的主键生成策略,如:
      • H2KeyGenerator
      • OracleKeyGenerator
      • PostgreKeyGenerator
  • 多数据源支持:详细使用参见https://github.com/baomidou/dynamic-datasource
    • Spring Boot 1.5.x ~ 2.x.x 使用dynamic-datasource-spring-boot-starter,支持 JDK 8 及以上版本
    • Spring Boot 3.x.x 使用dynamic-datasource-spring-boot3-starter要求 JDK 17 及以上
    • Spring Boot 4.x.x 使用dynamic-datasource-spring-boot4-starter要求 JDK 17 及以上

插件机制

常用插件

  1. 分页插件(PaginationInnerInterceptor)
    • 原理:MP 的分页不是内存分页,而是物理分页。它通过 MyBatis 的拦截器(Interceptor)机制,在 SQL 执行前重写 SQL(如加上LIMIT)。
    • 使用:配置MybatisPlusInterceptor,注入PaginationInnerInterceptor。代码中使用Page<T>对象接收结果。
  2. 乐观锁插件OptimisticLockerInnerInterceptor
    1. 读取记录时,获取当前的版本号(version)。
    2. 在更新记录时,将这个版本号一同传递。
    3. 执行更新操作时,设置version = newVersion的条件为version = oldVersion
    4. 如果版本号不匹配,则更新失败。
  3. 多租户插件TenantLineInnerInterceptor
    1. 是 MyBatis-Plus 提供的一个插件,用于实现多租户的数据隔离。通过这个插件,可以确保每个租户只能访问自己的数据,从而实现数据的安全隔离
    2. 默认插入 SQL 是需要判断租户条件,因此需要配合自动填充字段功能填充租户字段,否则租户字段不会自动保存到数据库
  4. 非法SQL拦截插件IllegalSQLInnerInterceptor
    • 用于拦截和检查非法SQL语句。该插件旨在帮助开发者在SQL执行前发现并解决潜在的安全问题,如全表更新、删除操作,以及对索引的检查等
  5. 防全表更新与删除插件BlockAttackInnerInterceptor
    1. 专门用于防止恶意的全表更新和删除操作。该插件通过拦截updatedelete语句,确保这些操作不会无意中影响到整个数据表,从而保护数据的完整性和安全性

执行流程

MyBatis-Plus(MP)插件的执行流程,本质上是基于MyBatis 的插件(Plugin)机制实现的。MP 利用这一机制,在 MyBatis 的核心执行流程中“插入”自己的逻辑,从而实现分页、性能分析、SQL 注入防护等功能。

MybatisPlusInterceptor是“包工头”,它实现了 MyBatis 的接口并拦下所有活;而List<InnerInterceptor>是“工人”,实现具体的功能

组件层级类/接口名称职责实现关系
顶层门面MybatisPlusInterceptor实现 MyBatis 原生Interceptor,作为唯一入口,管理插件列表。实现
org.apache.ibatis.
plugin.Interceptor
插件容器List<InnerInterceptor>存储具体的增强逻辑(如分页、乐观锁),由顶层门面调用。内部持有
具体逻辑PaginationInnerInterceptor
实现具体的业务逻辑(如重写 SQL、计算耗时)。实现
InnerInterceptor

如何自定义SQL

通过如下注解,可以实现自定义SQL

  • @Select: 查询
  • @Insert: 插入
  • @Update: 更新
  • @Delete: 删除
@MapperpublicinterfaceUserMapperextendsBaseMapper<User>{// 简单查询@Select("SELECT * FROM user WHERE email = #{email}")UserselectByEmail(@Param("email")Stringemail);// 复杂一点的条件查询@Select("SELECT * FROM user WHERE status = #{status} AND age > #{minAge}")List<User>selectByStatusAndAge(@Param("status")Integerstatus,@Param("minAge")IntegerminAge);}

mybatis知识

# {}${}的区别

  • #{}:是预编译处理(PreparedStatement)。MyBatis 会将它替换为?,能有效防止 SQL 注入
  • ${}:是字符串替换。直接将变量拼接到 SQL 中,存在注入风险,通常用于传入数据库表名或排序字段(ORDER BY

MyBatis 的一级缓存和二级缓存

  • 一级缓存:作用域为SqlSession。在同一个会话中,相同的查询不再查数据库。默认开启。
  • 二级缓存:作用域为Namespace(多个会话间共享)。需要手动开启,且实体类必须实现序列化接口。
  • 失效场景:任何的INSERT,UPDATE,DELETE操作都会刷新缓存

实体类属性名和表中字段名不一致怎么办?

  1. 在 SQL 语句中使用别名(AS)。
  2. 使用ResultMap进行映射(最常用)。
  3. 开启驼峰命名自动转换配置(mapUnderscoreToCamelCase

Mybatis的缓存机制

一级缓存建议保持默认(开启),而二级缓存通常不建议开启(默认也是关闭的),尤其是在复杂的业务或分布式系统中

一级缓存

一级缓存的实现参见:BaseExecutorPerpetualCache

  • 一级缓存的生命周期由Executor(执行器)管理。在BaseExecutor(所有执行器的基类)中,定义了本地缓存对象
  • SqlSession每次创建都会生成一个新的Executor,所以一级缓存是线程隔离的【参见DefaultSqlSessionFactory】

二级缓存

二级缓存的实现参见:CachingExecutorSynchronizedCache
当开启二级缓存后,MyBatis 会使用CachingExecutor包装原来的Executor

装饰器模式:二级缓存的实现非常优雅,PerpetualCache是基础,通过SynchronizedCache(同步)、LoggingCache(日志)、ScheduledCache(定时)、SerializedCache(序列化)、LruCache(回收策略)等装饰器层层包装,组合出最终需要的功能

特性一级缓存 (Local)二级缓存 (Global)
作用范围单个 SqlSession 内同一个 Mapper 命名空间内
数据共享独享,不跨会话共享,跨 SqlSession
默认状态开启关闭 (需手动配置)
生命周期伴随 SqlSession 的创建与关闭伴随 SqlSessionFactory 的生命周期
清空时机增删改操作、close()、commit()对应 Mapper 的增删改操作、commit()

是否开启

缓存类型建议配置理由适用场景
一级缓存开启 (默认)安全、自动管理、提升单次会话性能所有场景(无需干预)
二级缓存关闭 (默认)避免脏读、避免分布式不一致复杂业务、分布式系统
二级缓存开启 (需评估)需处理好序列化和跨表失效问题单机应用、数据字典、纯读场景

一句话建议:用好一级缓存,忘掉二级缓存,用 Redis 来做全局缓存

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/1 5:01:36

Miniconda-Python3.10镜像在数学解题大模型中的探索

Miniconda-Python3.10镜像在数学解题大模型中的探索 在人工智能推动科研范式变革的今天&#xff0c;数学解题大模型正从“能否理解题目”迈向“如何严谨推导”的深水区。这类模型不仅要解析自然语言描述的数学问题&#xff0c;还需进行符号运算、逻辑推理和多步演算——任务链…

作者头像 李华
网站建设 2026/5/1 5:05:14

Miniconda-Python3.10镜像如何助力AIaaS平台建设

Miniconda-Python3.10镜像如何助力AIaaS平台建设 在当今AI模型研发日益复杂的背景下&#xff0c;一个常见的痛点是&#xff1a;为什么同一个代码在研究员A的机器上能跑通&#xff0c;到了工程师B的生产环境却频频报错&#xff1f;问题往往不在于算法本身&#xff0c;而在于“运…

作者头像 李华
网站建设 2026/4/25 15:11:37

Miniconda环境下PyTorch自定义算子开发指南

Miniconda环境下PyTorch自定义算子开发指南 在深度学习模型日益复杂的今天&#xff0c;研究人员和工程师常常面临一个共同的挑战&#xff1a;如何在保证实验可复现性的同时&#xff0c;高效实现性能关键路径的底层优化&#xff1f;尤其是在训练过程中某个操作成为瓶颈时&#x…

作者头像 李华
网站建设 2026/5/1 9:56:50

Miniconda-Python3.10镜像支持Markdown格式实验记录管理

Miniconda-Python3.10镜像支持Markdown格式实验记录管理 在人工智能与数据科学项目日益复杂的今天&#xff0c;研究者们常面临一个看似简单却极为棘手的问题&#xff1a;为什么同样的代码&#xff0c;在同事的机器上运行正常&#xff0c;到了自己环境里却报错不断&#xff1f;更…

作者头像 李华
网站建设 2026/5/1 5:06:59

Miniconda配置PyTorch环境时如何优化pip安装速度

Miniconda配置PyTorch环境时如何优化pip安装速度 在深度学习项目开发中&#xff0c;搭建一个稳定、高效的Python环境往往是第一步。然而&#xff0c;许多开发者都曾经历过这样的场景&#xff1a;刚创建好Miniconda环境&#xff0c;执行pip install torch后终端卡住不动&#xf…

作者头像 李华
网站建设 2026/5/1 4:47:02

使用Miniconda实现PyTorch模型的版本灰度上线

使用Miniconda实现PyTorch模型的版本灰度上线 在AI系统日益复杂的今天&#xff0c;一个看似微小的模型更新&#xff0c;可能引发线上服务的连锁反应。你是否经历过这样的场景&#xff1a;本地训练效果出色的PyTorch模型&#xff0c;部署到生产环境后推理结果异常&#xff1f;或…

作者头像 李华