MyBatis-Plus 高级用法

发布时间:2026/10/24 14:32:34

MyBatis-Plus 高级用法 一、MyBatis-Plus 高级用法整体体系可以把 MyBatis-Plus 高级功能分成下面几层MyBatis-Plus │ ├── 1. 高级查询 │ ├── LambdaQueryWrapper │ ├── LambdaUpdateWrapper │ ├── 条件嵌套 │ ├── select 指定字段 │ ├── groupBy / having │ ├── exists / notExists │ └── apply / last │ ├── 2. 分页与批量 │ ├── PaginationInnerInterceptor │ ├── Page │ ├── selectPage │ ├── saveBatch │ └── updateBatchById │ ├── 3. 数据自动处理 │ ├── 自动填充 │ ├── 逻辑删除 │ ├── 枚举映射 │ └── 类型转换 │ ├── 4. 并发控制 │ └── Version 乐观锁 │ ├── 5. 插件体系 │ ├── 分页插件 │ ├── 乐观锁插件 │ ├── 防全表更新删除 │ ├── 多租户 │ ├── 数据权限 │ └── 动态表名 │ ├── 6. 自定义 SQL │ ├── Select │ ├── XML │ ├── Wrapper 参数 │ └── 自定义 Mapper │ └── 7. 企业级架构 ├── 多租户 ├── 数据权限 ├── 审计字段 ├── 分库分表 └── 权限过滤下面重点讲。二、LambdaQueryWrapper —— 最重要的高级查询方式如果你以前写QueryWrapperUserwrappernewQueryWrapper();wrapper.eq(username,admin).gt(age,18);更推荐LambdaQueryWrapperUserwrappernewLambdaQueryWrapper();wrapper.eq(User::getUsername,admin).gt(User::getAge,18);这样最大的好处是User::getUsername不会出现字符串字段写错的问题。例如wrapper.eq(User::getUserName,username)如果以后数据库字段或者 Java 属性发生变化IDE 可以帮助你发现问题。三、动态条件查询这是实际开发中非常常见的。例如publicListUsergetUserList(Stringusername,Integerage){LambdaQueryWrapperUserwrappernewLambdaQueryWrapper();wrapper.eq(StringUtils.hasText(username),User::getUsername,username).eq(age!null,User::getAge,age);returnuserMapper.selectList(wrapper);}如果username 张三 age null实际 SQL 类似WHEREusername张三如果username null age 20则WHEREage20这比手动拼接 SQL 优雅很多。四、条件嵌套这个在复杂查询中非常有用。例如WHEREusername张三AND(age18ORstatus1)MyBatis-Pluswrapper.eq(User::getUsername,张三).and(w-w.gt(User::getAge,18).or().eq(User::getStatus,1));还可以wrapper.and(w-w.eq(User::getStatus,1).or().eq(User::getStatus,2));这种方式对于后台管理系统的复杂搜索条件特别实用。五、select 指定查询字段很多人使用userMapper.selectList(wrapper);实际上会查询完整字段。如果表非常大没必要全部查询。可以wrapper.select(User::getId,User::getUsername,User::getEmail);最终类似SELECTid,username,emailFROMuser这个在用户列表下拉框搜索结果大数据量查询中特别有价值。六、groupBy / havingMyBatis-Plus 不只是简单 CRUD。例如SELECTdepartment_id,COUNT(*)FROMuserGROUPBYdepartment_idHAVINGCOUNT(*)10可以QueryWrapperUserwrappernewQueryWrapper();wrapper.select(department_id,COUNT(*) AS total).groupBy(department_id).having(COUNT(*) 10);这种场景一般用于统计报表 数据分析 后台 Dashboard七、apply / last —— 非常强但要谨慎例如wrapper.apply(DATE(create_time) {0},2026-08-24);可以执行一些复杂 SQL 条件。或者wrapper.last(LIMIT 10);生成LIMIT10但是last()不要直接拼接用户输入。例如不要wrapper.last(LIMIT userInput);否则存在 SQL 注入风险。八、分页查询这是 MyBatis-Plus 最常用的高级功能之一。配置分页插件BeanpublicMybatisPlusInterceptormybatisPlusInterceptor(){MybatisPlusInterceptorinterceptornewMybatisPlusInterceptor();interceptor.addInnerInterceptor(newPaginationInnerInterceptor(DbType.MYSQL));returninterceptor;}然后PageUserpagenewPage(1,10);PageUserresultuserMapper.selectPage(page,wrapper);可以获取result.getRecords();result.getTotal();result.getCurrent();result.getSize();result.getPages();非常适合前端page pageSize total records这种接口结构。九、自定义分页查询实际项目里经常不是简单selectPage()而是SELECTu.id,u.username,d.nameASdepartment_nameFROMuseruLEFTJOINdepartment dONu.department_idd.id这时候可以自定义 Mapper。例如IPageUserVOselectUserPage(PageUserVOpage,Param(username)Stringusername);XMLselectidselectUserPageresultTypecom.xxx.vo.UserVOSELECT u.id, u.username, d.name AS departmentName FROM user u LEFT JOIN department d ON u.department_id d.idwhereiftestusername ! null and username ! AND u.username LIKE CONCAT(%, #{username}, %)/if/where/select调用PageUserVOpagenewPage(1,10);IPageUserVOresultuserMapper.selectUserPage(page,username);这个是实际企业项目非常重要的能力。十、批量操作MyBatis-Plus 提供saveBatch()例如ListUserusersnewArrayList();users.add(user1);users.add(user2);users.add(user3);userService.saveBatch(users);还可以userService.saveBatch(users,500);表示每 500 条执行一次更新也有userService.updateBatchById(users);实际开发中导入Excel CSV 批量用户 批量题目 批量考试记录都非常常用。十一、逻辑删除例如数据库id username deleted实体TableLogicprivateIntegerdeleted;数据库0 正常 1 删除执行userMapper.deleteById(1);不会真正DELETEFROMuserWHEREid1而是UPDATEuserSETdeleted1WHEREid1同时普通查询selectList()会自动增加WHEREdeleted0这对用户 订单 课程 考试记录 学习记录非常常见。十二、自动填充比如每张表都有create_time update_time create_by update_by实体TableField(fillFieldFill.INSERT)privateLocalDateTimecreateTime;TableField(fillFieldFill.INSERT_UPDATE)privateLocalDateTimeupdateTime;然后ComponentpublicclassMetaObjectHandlerImplimplementsMetaObjectHandler{OverridepublicvoidinsertFill(MetaObjectmetaObject){this.strictInsertFill(metaObject,createTime,LocalDateTime.class,LocalDateTime.now());}OverridepublicvoidupdateFill(MetaObjectmetaObject){this.strictUpdateFill(metaObject,updateTime,LocalDateTime.class,LocalDateTime.now());}}以后userService.save(user);你不需要自己user.setCreateTime(...)框架自动处理。十三、乐观锁 Version这个非常值得掌握。假设用户 A 打开商品 用户 B 打开商品数据库stock 10 version 1A 修改stock 9 version 2B 此时还是version 1B 再修改UPDATEproductSETstock8,version2WHEREid1ANDversion1因为数据库已经version 2所以更新失败实体VersionprivateIntegerversion;配置BeanpublicMybatisPlusInterceptorinterceptor(){MybatisPlusInterceptorinterceptornewMybatisPlusInterceptor();interceptor.addInnerInterceptor(newOptimisticLockerInnerInterceptor());returninterceptor;}适用于库存 订单 账户余额 积分 考试次数 课程状态等并发修改场景。十四、防止全表 UPDATE / DELETE这是非常实用但很多人不知道的功能。例如代码出现userMapper.delete(null);可能直接变成DELETEFROMuser;这是非常危险的。可以使用BlockAttackInnerInterceptor例如interceptor.addInnerInterceptor(newBlockAttackInnerInterceptor());它可以阻止类似UPDATEuserSETstatus1;或者DELETEFROMuser;这种没有 WHERE 条件的危险 SQL。生产项目建议开启。十五、枚举自动映射例如publicenumUserStatus{DISABLED(0,禁用),ENABLED(1,正常);privatefinalIntegercode;privatefinalStringname;}数据库status 1JavaprivateUserStatusstatus;可以通过 MyBatis-Plus 的枚举能力实现EnumValueprivateIntegercode;这样数据库1自动转换成UserStatus.ENABLED比到处if(status1)更清晰。十六、自定义 SQL Wrapper这是一个非常重要的高级组合。假设你有LambdaQueryWrapperUserwrapper同时又需要自己写复杂 SQL。可以让 Wrapper 参与 XML SQL。例如IPageUserVOselectUserPage(PageUserVOpage,Param(Constants.WRAPPER)WrapperUserwrapper);XMLselectidselectUserPageresultTypecom.xxx.vo.UserVOSELECT u.id, u.username, u.email FROM user u ${ew.customSqlSegment}/selectJavaLambdaQueryWrapperUserwrappernewLambdaQueryWrapper();wrapper.eq(User::getStatus,1).like(User::getUsername,keyword);userMapper.selectUserPage(page,wrapper);这样就实现复杂 SQL MyBatis-Plus 条件构造器这是实际项目中非常好用的一种模式。十七、Service 层高级用法MyBatis-Plus 不只是 Mapper。通常publicinterfaceUserServiceextendsIServiceUser{}实现ServicepublicclassUserServiceImplextendsServiceImplUserMapper,UserimplementsUserService{}直接获得save()saveBatch()removeById()updateById()updateBatchById()getById()list()listByIds()count()page()例如userService.getById(id);userService.list();userService.count();userService.save(user);userService.updateById(user);十八、Service 层事务 批量操作例如创建订单TransactionalpublicvoidcreateOrder(OrderDTOdto){OrderordercreateOrder(dto);save(order);ListOrderItemitemscreateItems(dto);orderItemService.saveBatch(items);}如果订单保存成功 订单明细保存失败事务会回滚。这也是 MyBatis-Plus 和 Spring Boot 常见的组合。十九、多租户如果你的系统未来是 SaaS公司 A 公司 B 公司 C数据库user id tenant_id username用户 Atenant_id 1001用户 Btenant_id 1002查询userMapper.selectList(wrapper);框架自动增加WHEREtenant_id1001这就是 MyBatis-Plus 的TenantLineInnerInterceptor非常适合SaaS 教育平台 企业管理系统 多机构系统二十、数据权限这个和多租户很容易混淆。例如超级管理员 → 看所有数据 校长 → 看整个学校 老师 → 看自己的班级 学生 → 只能看自己的数据最终 SQL 可能需要WHEREschool_id1001ANDclass_id2001MyBatis-Plus 可以通过插件机制实现数据权限拦截。但这里需要注意数据权限通常不是简单加一个注解就完全解决。实际项目一般会结合Spring Security Sa-Token RBAC 自定义 SQL 拦截器 MyBatis-Plus InnerInterceptor一起设计。二十一、动态表名例如user_2025 user_2026 user_2027或者log_202608 log_202609可以使用DynamicTableNameInnerInterceptor根据当前请求动态决定表名。例如tableNameHandler根据当前月份 租户 业务类型决定最终访问log_202608这种一般用于日志、流水、历史数据。二十二、MyBatis-Plus 插件体系如果你真正想把 MyBatis-Plus 学到高级阶段我建议重点理解MybatisPlusInterceptor例如BeanpublicMybatisPlusInterceptormybatisPlusInterceptor(){MybatisPlusInterceptorinterceptornewMybatisPlusInterceptor();// 分页interceptor.addInnerInterceptor(newPaginationInnerInterceptor(DbType.MYSQL));// 乐观锁interceptor.addInnerInterceptor(newOptimisticLockerInnerInterceptor());// 防止全表更新删除interceptor.addInnerInterceptor(newBlockAttackInnerInterceptor());returninterceptor;}整个 MyBatis-Plus 的高级能力本质上很多都围绕Interceptor展开。二十三、一个比较完整的企业级配置例如ConfigurationMapperScan(com.example.mapper)publicclassMybatisPlusConfig{BeanpublicMybatisPlusInterceptormybatisPlusInterceptor(){MybatisPlusInterceptorinterceptornewMybatisPlusInterceptor();// 分页interceptor.addInnerInterceptor(newPaginationInnerInterceptor(DbType.MYSQL));// 乐观锁interceptor.addInnerInterceptor(newOptimisticLockerInnerInterceptor());// 防止全表更新、删除interceptor.addInnerInterceptor(newBlockAttackInnerInterceptor());returninterceptor;}}这已经是一个比较常见的生产级基础配置。二十四、MyBatis-Plus 和原生 MyBatis 怎么配合这是非常重要的一点。不要认为用了 MyBatis-Plus 就不能写 XML。实际上推荐简单 CRUD ↓ MyBatis-Plus 简单条件查询 ↓ LambdaQueryWrapper 复杂查询 ↓ MyBatis XML 多表 JOIN ↓ XML / 自定义 Mapper 复杂统计 ↓ XML 特殊 SQL ↓ 原生 MyBatis例如userMapper.selectById(id);用 MP。但是用户 ↓ 部门 ↓ 角色 ↓ 权限 ↓ 课程 ↓ 学习记录这种复杂查询直接写 XML 往往比强行使用 Wrapper 更合理。二十五、真正值得你掌握的几个高级组合如果你是为了面试 实际项目开发我建议重点掌握下面几个组合。① Lambda 动态条件LambdaQueryWrapper 条件判断这是日常开发最高频。② MP 分页Page LambdaQueryWrapper PaginationInnerInterceptor后台管理系统基本必用。③ MP XMLMyBatis-Plus CRUD 自定义 Mapper XML这是企业项目最实用的组合。④ 自动填充 逻辑删除TableLogic MetaObjectHandler非常适合管理系统。⑤ 乐观锁 事务Version Transactional解决并发更新问题。⑥ 插件体系重点理解MybatisPlusInterceptor │ ├── PaginationInnerInterceptor ├── OptimisticLockerInnerInterceptor ├── BlockAttackInnerInterceptor ├── TenantLineInnerInterceptor ├── DataPermissionInterceptor └── DynamicTableNameInnerInterceptor这个层面掌握以后你对 MyBatis-Plus 的理解就从“会 CRUD”提升到“理解框架”。
延伸阅读

更多相关文章

2026/10/23 12:28:36

GraphRAG深度认识:当大模型学会“理解关系”

引言:RAG的“天花板”与GraphRAG的破局检索增强生成(RAG)在过去两年里几乎成了每个AI应用的标配。通过从外部知识库中检索相关信息并注入大语言模型(LLM)的提示词中,RAG有效缓解了幻觉、知识陈旧和缺乏领域…

2026/10/24 17:55:40

C++期末高频失分点:运算符陷阱、指针误区与const底层逻辑

简介:本资源为华南理工大学《C程序设计基础》课程2016–2017学年第一学期期末考试A卷真题试卷,面向高校计算机类专业初学者及C入门学习者,聚焦夯实语法基础、强化逻辑分析与代码执行推演能力。试卷涵盖常量与变量辨析、逻辑运算符短路特性、条…

2026/10/24 17:55:40

高并发高可用大型网站架构设计与容量缓存冗余实战

简介:面向具备一定IT基础的工程师与架构师,这份指南聚焦大型网站高性能、高并发与高可用架构设计,帮助读者理解架构原则、分层优化策略及安全落地方法,适用于准备大规模扩展的中小互联网团队或正面临高流量挑战的成熟型企业参考。…

2026/10/24 17:55:40

博弈树与评估函数:计算机下棋的底层逻辑解剖

简介:本资源是面向计算机专业学生、人工智能初学者及算法竞赛备赛者的计算机博弈系统性入门辅导资料,聚焦机器博弈原理、主流棋类建模与算法实现路径。内容源自东北大学机器博弈研究室教学课件,涵盖棋类分类(中国象棋、国际象棋、…

2026/10/24 17:55:40

SAP库存调拨五类移动类型原理与MRP协同实战

简介:本资源是一份面向SAP MM模块初、中级实施顾问与库存管理从业者的深度实践指南,聚焦企业高频场景——库存调拨与发货全流程配置与操作。内容系统梳理MB1B事务码下五类关键移动类型(311/313/315一步与二步转储、301/303/305工厂间调拨、30…

2026/10/24 17:55:40

MilkShape 3D 1.8.2:老游戏模型修改与SMD导出实战指南

简介:一份面向游戏建模新手与中世纪II模组玩家的实用资源,提供经典3D建模与修改工具MilkShape 3D 1.8.2的rar安装包,安装后即可用于初级模型修改实践。该版本操作环境稳定,支持MD2、MD3、MD5、SMD、X、ASE等常见三维模型格式&…

2026/10/23 22:56:35

金融AI落地指南:从调研报告到技术选型与工程实践

简介:这份PDF报告聚焦2025年金融服务业中国AI现状与趋势,面向金融科技从业者、AI战略规划人员及关注行业数字化转型的研究者,帮助读者把握生成式AI在银行、支付、交易等场景中的落地路径与投资方向。资源包内含1个PDF文件,大小约1…

2026/10/24 0:02:40

MATLAB缩进快捷键与批量格式化实战指南

1. 被自动缩进折磨的那些年如果你写过MATLAB代码,大概率经历过这种场景:从某个文档、网页或者聊天记录里复制了一段代码,粘贴进编辑器之后,每一行前面都带着莫名其妙的空格,有的行首是四个空格,有的是一个T…

2026/10/24 0:02:40

用Poco实现Qt风格信号与槽的跨平台C++方案

简介:本资源是一份面向C中级开发者的技术实践工程,聚焦于在非Qt框架环境下模拟实现Qt核心通信机制——信号与槽,借助Poco网络库的事件系统完成解耦式对象通信。适用于需在跨平台C项目中引入松耦合回调机制、但受限于无法集成Qt依赖的开发场景…

2026/10/24 0:02:40

ESXi裸机虚拟化安装指南:从硬件兼容到虚拟机部署

1. 为什么还要折腾ESXi:从一台闲置机器说起手里攒了几台淘汰下来的迷你主机,配置不算差,i5加16G内存,扔了可惜,装个桌面系统又觉得浪费。这种场景下,ESXi就成了一个绕不开的选择。它是一套裸机虚拟化平台&a…

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

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

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