MyBatis-Plus 核心功能详解:条件构造器、自定义 SQL 与主键策略

发布时间:2026/11/4 9:13:37

MyBatis-Plus 核心功能详解:条件构造器、自定义 SQL 与主键策略 1. 引言MyBatis-Plus简称 MP是 MyBatis 的增强工具在 MyBatis 的基础上只做增强不做改变为简化开发、提高效率而生。它内置了通用 Mapper、通用 Service几乎可以不用写 SQL 就能完成单表 CRUD 操作同时保留了 MyBatis 的灵活性支持自定义 SQL、分页插件、乐观锁插件等强大功能。本文将围绕 MyBatis-Plus 的核心功能展开重点讲解条件构造器Wrapper、自定义 SQL、主键策略、分页插件、乐观锁等核心特性的实现原理与使用方式帮助读者从原理层面理解 MP 的设计思想。2. MyBatis-Plus 核心功能总览MyBatis-Plus 的核心功能可以概括为以下几个方面通用 CRUD内置 BaseMapper 与 IService提供单表增删改查的通用方法无需编写 SQL。条件构造器Wrapper通过面向对象的链式 API 构造查询条件支持 Lambda 表达式编译期校验字段名。自定义 SQL支持在 XML 或注解中编写自定义 SQL并可与 Wrapper 结合实现动态条件拼接。分页插件基于 MyBatis 拦截器实现物理分页自动生成 COUNT 查询。乐观锁插件通过版本号字段实现乐观锁自动拼接SET version version 1。主键策略支持雪花算法、自增、UUID 等多种主键生成策略。逻辑删除通过全局配置实现逻辑删除自动拼接deleted 0条件。代码生成器一键生成 Entity、Mapper、Service、Controller 等全套代码。整体架构如下图所示业务代码BaseMapper / IService条件构造器 WrapperSQL 解析与拼接MyBatis 执行器数据库分页插件 / 乐观锁插件3. 条件构造器Wrapper原理与使用3.1 Wrapper 是什么Wrapper 是 MyBatis-Plus 中用于封装查询条件的核心抽象类它把 SQL 中的WHERE、ORDER BY、GROUP BY、HAVING等子句抽象为 Java 对象通过链式调用构造查询条件。Wrapper 的继承体系如下WrapperT ├── AbstractWrapperT │ ├── QueryWrapperT │ ├── UpdateWrapperT │ └── LambdaQueryWrapperT │ └── LambdaUpdateWrapperT3.2 核心实现原理Wrapper 的核心原理是将条件表达式解析为 SQL 片段。以QueryWrapper为例调用eq(name, 张三)时内部会生成一个MergeSegments对象将条件片段按AND/OR组合最终在getSqlSegment()方法中拼接为完整的 SQL 片段。关键源码逻辑如下// AbstractWrapper 中的核心方法publicChildreneq(Rcolumn,Objectval){returnaddCondition(true,column,SqlKeyword.EQ,val);}privateChildrenaddCondition(booleancondition,Rcolumn,SqlKeywordkeyword,Objectval){// 将条件封装为 QueryCondition 对象存入条件列表queryConditions.add(newQueryCondition(column,keyword,val));return(Children)this;}当执行selectList(wrapper)时MP 会调用wrapper.getSqlSegment()生成WHERE子句再通过TableInfo将实体字段映射为数据库列名最终拼装成完整 SQL。3.3 常用 API 示例// 查询年龄大于 18 且姓名包含张的用户QueryWrapperUserwrappernewQueryWrapper();wrapper.gt(age,18).like(name,张).orderByDesc(create_time);ListUserusersuserMapper.selectList(wrapper);3.4 Lambda 条件构造器Lambda 条件构造器通过LambdaQueryWrapper使用实体类的getter方法引用代替字符串字段名编译期即可校验字段是否存在避免运行时因字段名拼写错误导致异常。LambdaQueryWrapperUserwrappernewLambdaQueryWrapper();wrapper.gt(User::getAge,18).like(User::getName,张).orderByDesc(User::getCreateTime);ListUserusersuserMapper.selectList(wrapper);Lambda 的实现原理是通过SerializedLambda解析方法引用提取出对应的属性名再结合TableInfo映射为数据库列名。4. 自定义 SQL 的实现方式4.1 为什么需要自定义 SQL虽然 MP 提供了通用 CRUD但在多表联查、复杂子查询、特定数据库函数等场景下仍需要手写 SQL。MP 支持两种自定义 SQL 的方式注解方式和 XML 方式。4.2 注解方式publicinterfaceUserMapperextendsBaseMapperUser{Select(SELECT * FROM user WHERE age #{age} AND name LIKE CONCAT(%, #{name}, %))ListUserselectByCondition(Param(age)Integerage,Param(name)Stringname);}4.3 XML 方式mappernamespacecom.example.mapper.UserMapperselectidselectUserPageresultTypecom.example.entity.UserSELECT * FROM userwhereiftestname ! null and name ! AND name LIKE CONCAT(%, #{name}, %)/ififtestage ! nullAND agegt;#{age}/if/where/select/mapper4.4 自定义 SQL 结合 WrapperMP 最强大的特性之一是自定义 SQL 与 Wrapper 结合可以在自定义 SQL 中动态拼接 Wrapper 生成的 WHERE 条件Select(SELECT * FROM user ${ew.customSqlSegment})ListUserselectByWrapper(Param(Constants.WRAPPER)WrapperUserwrapper);调用时LambdaQueryWrapperUserwrappernewLambdaQueryWrapper();wrapper.gt(User::getAge,18).like(User::getName,张);ListUserusersuserMapper.selectByWrapper(wrapper);这里的${ew.customSqlSegment}会被替换为 Wrapper 生成的WHERE子句实现自定义 SQL 与动态条件的完美结合。5. 主键策略5.1 主键策略类型MyBatis-Plus 支持多种主键生成策略通过TableId注解的type属性指定策略说明IdType.AUTO数据库自增依赖数据库的自增主键IdType.INPUT用户手动输入不自动生成IdType.ASSIGN_ID默认策略使用雪花算法生成分布式 IDIdType.ASSIGN_UUID使用 UUID 生成主键IdType.NONE不指定跟随全局配置5.2 雪花算法原理雪花算法Snowflake是 Twitter 开源的分布式 ID 生成算法生成的 ID 是一个 64 位的 Long 型整数结构如下| 1 bit 符号位 | 41 bit 时间戳 | 10 bit 机器 ID | 12 bit 序列号 |符号位固定为 0保证 ID 为正数。时间戳毫秒级时间戳可保证 69 年的使用期限。机器 ID区分不同机器支持最多 1024 台机器。序列号同一毫秒内的递增序列支持每毫秒生成 4096 个 ID。// 使用示例TableId(typeIdType.ASSIGN_ID)privateLongid;5.3 全局配置mybatis-plus:global-config:db-config:id-type:assign_id6. 分页插件6.1 分页插件原理MyBatis-Plus 的分页插件基于 MyBatis 的**拦截器Interceptor**机制实现。在执行 SQL 前拦截器会拦截Executor.query()方法解析出原始 SQL自动生成 COUNT 查询和分页 SQL。ConfigurationpublicclassMybatisPlusConfig{BeanpublicMybatisPlusInterceptormybatisPlusInterceptor(){MybatisPlusInterceptorinterceptornewMybatisPlusInterceptor();interceptor.addInnerInterceptor(newPaginationInnerInterceptor(DbType.MYSQL));returninterceptor;}}6.2 分页使用示例PageUserpagenewPage(1,10);// 第 1 页每页 10 条LambdaQueryWrapperUserwrappernewLambdaQueryWrapper();wrapper.gt(User::getAge,18);PageUserresultuserMapper.selectPage(page,wrapper);System.out.println(总记录数result.getTotal());System.out.println(总页数result.getPages());System.out.println(当前页数据result.getRecords());6.3 分页 SQL 生成过程以 MySQL 为例原始 SQL 为SELECT*FROMuserWHEREage18分页插件会生成两条 SQL-- COUNT 查询SELECTCOUNT(*)FROMuserWHEREage18-- 分页查询SELECT*FROMuserWHEREage18LIMIT0,107. 乐观锁插件7.1 乐观锁原理乐观锁假设并发冲突较少在更新时通过版本号判断数据是否被修改。更新前先查询版本号更新时携带版本号并执行SET version version 1若版本号不匹配则更新失败。7.2 配置与使用// 实体类中增加版本字段VersionprivateIntegerversion;ConfigurationpublicclassMybatisPlusConfig{BeanpublicMybatisPlusInterceptormybatisPlusInterceptor(){MybatisPlusInterceptorinterceptornewMybatisPlusInterceptor();interceptor.addInnerInterceptor(newOptimisticLockerInnerInterceptor());returninterceptor;}}7.3 更新 SQL 生成执行updateById(user)时MP 自动生成如下 SQLUPDATEuserSETname?,versionversion1WHEREid?ANDversion?若更新影响行数为 0说明版本号已被其他事务修改需要重试或提示用户。8. 逻辑删除8.1 逻辑删除原理逻辑删除并非真正删除数据而是通过标记字段如deleted将数据标记为已删除。查询时自动拼接deleted 0条件删除时自动执行UPDATE语句。8.2 配置与使用TableLogicprivateIntegerdeleted;mybatis-plus:global-config:db-config:logic-delete-field:deletedlogic-delete-value:1logic-not-delete-value:0执行deleteById(1L)时实际执行的 SQL 为UPDATEuserSETdeleted1WHEREid1ANDdeleted09. 总结MyBatis-Plus 通过封装通用 CRUD、条件构造器、分页插件、乐观锁、逻辑删除等能力大幅提升了开发效率。其核心设计思想是约定优于配置与只增强不改变条件构造器将 SQL 条件抽象为 Java 对象配合 Lambda 表达式实现编译期校验。自定义 SQL保留了 MyBatis 的灵活性并可与 Wrapper 无缝结合。分页与乐观锁插件基于 MyBatis 拦截器机制对业务代码零侵入。主键策略通过雪花算法解决了分布式场景下的 ID 生成问题。掌握这些核心功能的原理不仅能更高效地使用 MyBatis-Plus还能在遇到复杂业务场景时灵活扩展写出更优雅的代码。
延伸阅读

更多相关文章

2026/11/1 3:02:25

5个Obsidian AI技能:从零到一搭建你的笔记自动化工作流

5个Obsidian AI技能:从零到一搭建你的笔记自动化工作流 【免费下载链接】obsidian-skills Agent skills for Obsidian. Teach your agent to use Obsidian CLI and open formats including Markdown, Bases, JSON Canvas. 项目地址: https://gitcode.com/GitHub_T…

2026/10/27 1:10:51

BT下载慢?3步配好Tracker,P2P下载加速实操教程

BT下载慢?3步配好Tracker,P2P下载加速实操教程 【免费下载链接】trackerslist Updated list of public BitTorrent trackers 项目地址: https://gitcode.com/GitHub_Trending/tr/trackerslist BT下载速度上不去,多半不是宽带的锅&…

2026/11/4 9:09:20

CosyVoice智能玩具改造:零样本音色克隆让玩偶开口说话

1. 项目缘起与整体设计思路拆解家里那台被孩子玩腻了扔在角落的毛绒玩偶,其实藏着一个被大多数人忽略的改造空间。我最初动这个念头,是因为孩子总对着玩偶自言自语,而玩偶只会沉默地坐着。市面上带语音交互的智能玩具动辄几百上千&#xff0c…

2026/11/4 9:09:20

PyTorch张量创建与优化:从基础到高效实践

1. PyTorch张量基础认知:从概念到核心价值 在深度学习领域,数据就像建筑工地的砖块,而PyTorch张量(Tensor)就是这些砖块的标准化容器。我至今记得第一次用 torch.tensor([1,2,3]) 创建向量时那种"原来如此"…

2026/11/4 9:09:20

Access 2007 数据分析入门:建表、SQL聚合与交叉表查询

简介:这份PDF读本面向希望提升数据分析能力的Access 2007用户,原书由微软认证应用程序开发师迈克尔亚历山大撰写,重点讲清借助关系型数据库开展可扩展、过程透明且数据与呈现分离的分析思路,并与Excel的使用边界作对照。内容从建表…

2026/11/4 9:09:20

Jev不说话模型:TypeSafe AI与概率化决策的工程实践

1. 从“不说话”说起:Jev 到底在解决什么问题 第一次看到“不说话模型”这个说法,我脑子里蹦出来的画面是那种在群里从不闲聊、只在关键节点甩出一句结论的老工程师。Jev 给我的感觉就是这样——它不跟你寒暄,不给你写小作文,也不…

2026/11/4 9:09:20

TDengine容灾演练与数据一致性校验实践

1. 容灾演练的必要性与挑战在数据库运维领域,有一个残酷的现实:那些从未经过实战检验的容灾方案,往往会在关键时刻掉链子。我见过太多企业投入数百万构建的"完美"灾备系统,在真正需要切换时暴露出各种致命问题——从网络…

2026/11/4 9:04:19

解决IDEA中Spring Boot配置自动补全失效问题

1. 问题现象与背景分析 最近在IntelliJ IDEA中开发Spring Boot项目时,突然发现application.properties和application.yml文件失去了代码自动补全功能。这个问题看似不大,却严重影响开发效率——每次输入配置属性时都得手动查阅文档,稍不注意就…

2026/11/3 7:47:06

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/3 14:24:53

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/4 0:03:20

AI辅助技术栈评估:提升研发决策效率60%

1. 项目背景与核心价值技术决策一直是研发团队面临的重大挑战。随着技术生态的快速演进,技术栈的选择、维护和迭代变得愈发复杂。我们团队在过去两年里,先后经历了三次重大技术栈迁移,每次都需要投入大量人力进行技术评估和风险分析。直到去年…

2026/11/4 0:03:20

从生成Token到直接决策:Jev如何重塑AI Agent工程实践

1. 从"生成文字"到"拍板决策":Jev 到底在解决什么问题大多数人第一次接触大模型,脑子里建立的模型是"输入问题、输出文字"。你问它今天天气怎么样,它给你一段描述;你让它写个周报,它给你…

2026/11/4 0:03:20

32G统一内存跑大模型:内存账、TPS实测与端云分流

想在一台 32G 统一内存的小主机上把大模型跑成"日常可用",这件事我前后折腾了小半年。标题里说的这台 Mac mini M6,是我们这次讨论的目标平台,具体到手规格以实物为准;但下面这套推算方法和实测思路,对任何统…

2026/11/3 7:47:06

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/3 14:24:53

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑