MyBatis-Plus的条件构造器Wrapper怎么用_链式编程实现复杂查询条件拼接

云宇酱_6970

云宇酱_6970

2026-03-22

851人浏览

原创

wrapper链式调用失效因方法返回新实例而非原对象,属不可变设计;正确写法需链式调用或赋值,避免引用丢失。

mybatis-plus的条件构造器wrapper怎么用_链式编程实现复杂查询条件拼接

Wrapper 链式调用为什么拼着拼着就失效了

因为 Wrapper 的大多数方法(如 eq()、like()、in())返回的是新实例,不是原对象——它内部是不可变设计。你以为在“往同一个对象上加条件”,其实每次都在生成新对象,旧引用早就断了。

  • 错误写法:QueryWrapper<user> w = new QueryWrapper(); w.eq("age", 18); userMapper.selectList(w);</user> → 这里 eq() 返回了新 QueryWrapper,但你没接住,w 还是空的
  • 正确写法:必须链式或赋值,比如 userMapper.selectList(new QueryWrapper<user>().eq("age", 18).like("name", "张"))</user>
  • 如果中间要分支判断,别用临时变量覆盖原引用,改用 apply() 或提前构造好再传入,或者用 LambdaQueryWrapper 配合 if 块内直接调用

LambdaQueryWrapper 比 QueryWrapper 少踩一半坑

QueryWrapper 用字符串写字段名,编译不检查,重构时字段一改就报 org.apache.ibatis.reflection.ReflectionException;LambdaQueryWrapper 用方法引用来指定字段,IDE 能跳转、能重命名、编译期报错。

  • 安全写法:new LambdaQueryWrapper<user>().eq(User::getAge, 25).like(User::getName, "李")</user>
  • 注意:不能对 null 字段引用,比如 User::getDeleted 如果是布尔包装类且可能为 null,eq() 会抛 NPE;建议先判空,或用 isNull()/isNotNull()
  • 不支持动态表名或字段名——Lambda 形式锁死了实体类结构,想运行时拼字段?只能退回 QueryWrapper + 字符串,但得自己兜底校验

多个 or 条件嵌套时,and 和 or 的优先级怎么控制

MyBatis-Plus 的 or() 默认是和上一级同级的 or,不是括号内的 or。想表达 (a=1 AND (b=2 OR c=3)),必须显式用 and() + or() 函数式写法包裹。

  • 错误理解:w.eq("a", 1).and(i -> i.eq("b", 2).or().eq("c", 3)) → 这个 or() 是和 eq("b", 2) 并列,实际生成 a=1 AND (b=2 OR c=3),是对的
  • 但写成 w.eq("a", 1).eq("b", 2).or().eq("c", 3) 就变成 (a=1 AND b=2) OR c=3,容易误读
  • 真正需要多层括号时,用 and() 接一个 Consumer<children></children>,里面再嵌 or(),例如:and(q -> q.eq("x", 1).or(r -> r.like("y", "a").like("z", "b")))

Wrapper 传参为空时怎么避免查出全表

用户没输任何搜索条件,你却执行了 select * from user where 1=1 —— 这是 QueryWrapper 默认行为,也是线上慢查询常见源头。

  • 最简单防御:在 service 层加空校验,if (wrapper.getExpression() == null) { throw new IllegalArgumentException("查询条件不能为空"); }
  • 更稳妥做法:用 EmptyWrapper 替代默认空 Wrapper,或者初始化时就设 last("LIMIT 0"),等条件补全再用 clear() 清掉
  • 注意 lambdaQuery().eq(null, null) 不会报错,但会生成 WHERE column IS NULL,如果字段不允许 null,这条件永远不命中——看着像没查,实则全表扫描后无结果

Wrapper 的链式调用看着流畅,但每个点都是引用切换;字段写错、空值处理、括号层级、空条件放行——四点里漏一个,查出来的数据就不是你要的。

编程速学教程(入门课程)
编程速学教程(入门课程)

编程怎么学习?编程怎么入门?编程在哪学?编程怎么学才快?不用担心,这里为大家提供了编程速学教程(入门课程),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
mybatis一级缓存和二级缓存
mybatis一级缓存和二级缓存

在MyBatis中,一级缓存和二级缓存是两种不同级别的缓存机制,它们都可以用来提高性能。本专题提供mybatis一级缓存和二级缓存相关文章,大家可以免费阅读。

2023.08.21

583

4

ibatis和mybatis有什么区别
ibatis和mybatis有什么区别

ibatis和mybatis的区别:1、基本信息不同;2、开发时间不同;3、功能与易用性;4、配置文件;5、入参类型与出参类型;6、返回结果集接受方式;7、语法差异;8、数据库方言支持;9、插件支持;10、社区活跃度;11、全球化支持。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.02.23

2562

5

mybatis如何配置数据库连接
mybatis如何配置数据库连接

mybatis配置数据库连接的方法:1、指定数据源;2、配置事务管理器;3、配置类型处理器和映射器;4、使用环境元素;5、配置别名。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.02.23

446

5

mybatis工作原理及流程是什么
mybatis工作原理及流程是什么

mybatis工作原理及流程:1、配置文件;2、接口与映射;3、sql解析与生成;4、执行计划;5、结果处理;6、动态sql;7、缓存机制;8、插件;9、事务管理;10、日志与监控;11、扩展性。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.02.23

292

4

hibernate和mybatis有哪些区别
hibernate和mybatis有哪些区别

hibernate和mybatis的区别:1、实现方式;2、性能;3、对象管理的对比;4、缓存机制。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.02.23

302

5

Java MyBatis框架
Java MyBatis框架

本专题专注于Java主流ORM框架MyBatis的应用,系统讲解SQL映射、动态SQL、结果映射、分页查询、缓存机制与多表关联等核心内容,并结合企业管理系统、电商平台和后台管理项目实战,帮助学员全面掌握高效的数据库持久层开发技能。

2025.08.26

5809

22

OpenJDK JVM参数怎么调优
OpenJDK JVM参数怎么调优

Java应用运行缓慢,如何调整JVM参数?本专题介绍OpenJDK JVM性能调优的基本流程,涵盖性能指标确认、运行数据采集、内存配置和垃圾回收分析,帮助你先定位瓶颈,再通过对照测试验证效果,避免直接套用参数而影响应用稳定性。

2026.10.16

60

10

OpenJDK怎么配置Java开发环境
OpenJDK怎么配置Java开发环境

怎样用OpenJDK搭建开发环境?本专题介绍版本选择、下载安装、环境变量配置和编译运行验证,帮助你理清JDK的作用及基本配置流程,并通过简单程序检查环境是否可用,为后续项目开发做好准备。

2026.10.16

40

10

OpenJDK怎么部署Java应用
OpenJDK怎么部署Java应用

Java项目开发完成后,怎样部署到目标环境并正常运行?本专题介绍OpenJDK应用部署流程,涵盖运行环境准备、版本兼容检查、应用打包、启动参数配置和日志查看,帮助你理清部署前后的操作顺序,减少环境差异造成的运行问题。

2026.10.16

40

10

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
phpStudy极速入门视频教程
phpStudy极速入门视频教程

共6课时 | 54.7万人学习

独孤九贱(4)_PHP视频教程
独孤九贱(4)_PHP视频教程

共89课时 | 133.8万人学习