Java 数据 01:MyBatis-Plus 复杂查询(Lambda+Wrapper 多条件)
MyBatis-Plus 的复杂查询是日常开发中最常用的功能之一尤其当条件动态、多字段组合、嵌套逻辑and/or、范围查询、分页排序等场景时LambdaQueryWrapper是目前2025–2026 年最推荐的方式。它比老的QueryWrapper更安全编译期就能发现字段名写错、更现代Lambda 方法引用、代码可读性更高。下面给你一个系统、由浅入深、覆盖 90% 真实场景的详解。1. 为什么选 LambdaQueryWrapper 而不是 QueryWrapper维度QueryWrapperLambdaQueryWrapper推荐场景2026共识字段安全字符串age改字段名易出错User::getAge编译期检查Lambda 完胜可读性一般极高像写 Java 代码LambdaIDE 提示弱字符串强方法引用跳转Lambda动态条件支持支持更优雅都行但 Lambda 更简洁嵌套 or/and需要嵌套 Wrapper支持 lambda 嵌套更直观Lambda 更友好社区主流老项目多新项目 95% 都在用 LambdaLambda结论新项目一律用 LambdaQueryWrapper老项目逐步迁移。2. 快速入门三种创建方式记一种就行// 方式1最推荐Wrappers 工具类LambdaQueryWrapperUserwrapperWrappers.UserlambdaQuery();// 方式2new 出来LambdaQueryWrapperUserwrappernewLambdaQueryWrapper();// 方式3从 QueryWrapper 转偶尔用LambdaQueryWrapperUserwrappernewQueryWrapperUser().lambda();3. 常见条件方法速查Lambda 版需求代码示例User 实体生成的 SQL 片段大致等于 eq.eq(User::getAge, 18)age 18不等于 ne.ne(User::getStatus, 0)status 0大于 gt.gt(User::getScore, 90)score 90大于等于 ge.ge(User::getCreateTime, startDate)create_time ?小于 lt / le.lt(User::getAge, 30)age 30模糊 like.like(User::getName, 张)name LIKE %张%左模糊 likeLeft.likeLeft(User::getPhone, 138)phone LIKE 138%右模糊 likeRight.likeRight(User::getEmail, qq.com)email LIKE %qq.comin.in(User::getId, idsList)id IN (1,3,5)notIn.notIn(User::getRoleId, excludeRoles)role_id NOT IN (...)between.between(User::getAge, 18, 35)age BETWEEN 18 AND 35isNull / isNotNull.isNull(User::getDeleteTime)delete_time IS NULLorderByAsc / Desc.orderByAsc(User::getCreateTime)ORDER BY create_time ASCgroupBy.groupBy(User::getDeptId)GROUP BY dept_idhaving.having(count(*) {0}, 5)HAVING count(*) 54. 动态条件最常见场景publicListUserVOsearchUsers(UserQueryDTOdto){LambdaQueryWrapperUserwrapperWrappers.UserlambdaQuery()// 姓名模糊前端传空串也安全.like(StringUtils.isNotBlank(dto.getName()),User::getName,dto.getName())// 年龄范围两个都传才加 between.between(dto.getMinAge()!nulldto.getMaxAge()!null,User::getAge,dto.getMinAge(),dto.getMaxAge())// 状态枚举或 Integer.eq(dto.getStatus()!null,User::getStatus,dto.getStatus())// 注册时间范围LocalDateTime.ge(dto.getStartTime()!null,User::getCreateTime,dto.getStartTime()).le(dto.getEndTime()!null,User::getCreateTime,dto.getEndTime())// 部门多选in.in(CollectionUtils.isNotEmpty(dto.getDeptIds()),User::getDeptId,dto.getDeptIds())// 排序默认创建时间降序.orderByDesc(User::getCreateTime);returnuserMapper.selectList(wrapper);}5. 复杂嵌套and / or 组合——高频面试 生产痛点// 需求(姓名 like 张% OR 手机号 like 138%) AND 年龄 18 AND (状态1 OR 角色 in (2,3))LambdaQueryWrapperUserwrapperWrappers.UserlambdaQuery().and(w-w.likeRight(User::getName,张).or().likeLeft(User::getPhone,138)).ge(User::getAge,18).and(w-w.eq(User::getStatus,1).or().in(User::getRoleId,2,3));// 更复杂的嵌套三层.and(w-w.or(w1-w1.eq(User::getType,1).ge(User::getScore,90)).or(w2-w2.eq(User::getType,2).between(User::getAge,20,30)))小技巧嵌套层级多时用变量抽取子 wrapper可读性更好LambdaQueryWrapperUserorNameOrPhoneWrappers.UserlambdaQuery().likeRight(User::getName,search).or().likeLeft(User::getPhone,search);wrapper.and(orNameOrPhone::apply);// 注意 apply 写法6. 分页 排序 常用组合写法// IService / BaseMapper 通用分页IPageUserpageuserService.page(newPage(dto.getPageNum(),dto.getPageSize()),wrapper);// 或直接用 mapperIPageUserpageResultuserMapper.selectPage(newPage(1,10),wrapper);7. LambdaUpdateWrapper更新时也推荐// 批量逻辑删除软删LambdaUpdateWrapperUserupdateWrapperWrappers.UserlambdaUpdate().set(User::getDeleted,1).set(User::getDeleteTime,LocalDateTime.now()).in(User::getId,idList).eq(User::getDeleted,0);// 防止重复删userMapper.update(null,updateWrapper);// 涨积分条件更新LambdaUpdateWrapperUserincScoreWrappers.UserlambdaUpdate().setSql(score score 10).eq(User::getId,userId);userMapper.update(null,incScore);8. 2025–2026 最佳实践建议永远用Wrappers.lambdaQuery()/Wrappers.lambdaUpdate()创建动态条件用条件表达式, 字段, 值三元写法避免if包裹一堆.eq()模糊查询默认前后模糊敏感字段建议用likeRight/likeLeft时间范围统一用LocalDateTime避免时区坑索引友好排序字段、分组字段、频繁 where 字段要建索引大列表 in 查询超过 1000 条 → 分批或改用 join 子查询生产日志可通过wrapper.getSqlSegment()或 MyBatis-Plus 日志打印完整 SQL你现在遇到的具体场景是哪种前端多条件搜索姓名/手机号/时间范围/状态嵌套 or and 的权限过滤批量更新/逻辑删除分页 排序 统计告诉我 DTO 结构或需求我可以直接写出最合适的 wrapper 代码。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2437593.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!