当前位置: 首页 > news >正文

深入理解 MyBatis-Plus 的 QueryWrapper:动态 SQL 构建的利器

关键词:MyBatis-Plus、QueryWrapper、动态 SQL、Java、ORM


一、引言

在 Java 后端开发中,MyBatis-Plus(简称 MP)作为 MyBatis 的增强工具,极大地简化了 CRUD 操作。而其中最核心的功能之一,就是动态 SQL 的条件构造器 —— QueryWrapper

你是否还在手写 XML 中的 <if test="...">?是否还在为拼接 SQL 条件而烦恼?QueryWrapper 将带你告别这些痛苦。


二、什么是 QueryWrapper?

QueryWrapper 是 MyBatis-Plus 提供的条件构造器,用于构建 WHERE 子句的查询条件。它通过链式调用的方式,实现了类型安全、可读性强、可复用的 SQL 构造。

类图关系(简化)

QueryWrapper ← AbstractWrapper ← Wrapper
  • Wrapper:抽象根类,定义了条件构造的基本能力。
  • AbstractWrapper:封装了条件拼接逻辑。
  • QueryWrapper:专用于查询操作,支持 SELECT ... WHERE ...

三、快速入门

1. 引入依赖

<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.5</version>
</dependency>

2. 实体类

@Data
@TableName("user")
public class User {private Long id;private String name;private Integer age;private String email;
}

3. Mapper 接口

public interface UserMapper extends BaseMapper<User> {}

4. 使用 QueryWrapper 查询

@Autowired
private UserMapper userMapper;public List<User> getUsers(String name, Integer minAge) {QueryWrapper<User> wrapper = new QueryWrapper<>();wrapper.like(StringUtils.isNotBlank(name), "name", name).ge(minAge != null, "age", minAge);return userMapper.selectList(wrapper);
}

四、核心方法详解

方法名说明示例
eq等于eq("age", 20)age = 20
ne不等于ne("age", 20)age <> 20
gt / ge大于 / 大于等于gt("age", 18)age > 18
lt / le小于 / 小于等于lt("age", 30)age < 30
like模糊查询like("name", "张")name LIKE '%张%'
in包含in("id", 1, 2, 3)id IN (1,2,3)
isNull / isNotNull空值判断isNull("email")email IS NULL
orderByAsc / orderByDesc排序orderByDesc("create_time")

五、进阶用法

1. 条件优先级(括号控制)

wrapper.and(w -> w.eq("age", 20).or().eq("name", "Tom")).eq("status", 1);

生成的 SQL:

WHERE (age = 20 OR name = 'Tom') AND status = 1

2. 只查询部分字段

wrapper.select("id", "name").eq("age", 25);

3. 排除字段

wrapper.select(User.class, info -> !info.getColumn().equals("password")).eq("status", 1);

六、实战案例:分页 + 多条件搜索

public IPage<User> searchUsers(String name, Integer minAge, Integer maxAge, int current, int size) {QueryWrapper<User> wrapper = new QueryWrapper<>();wrapper.like(StringUtils.isNotBlank(name), "name", name).ge(minAge != null, "age", minAge).le(maxAge != null, "age", maxAge).orderByDesc("create_time");Page<User> page = new Page<>(current, size);return userMapper.selectPage(page, wrapper);
}

七、常见误区与注意事项

误区正确做法
直接拼接字段名使用 LambdaQueryWrapper 避免硬编码
忽略空值判断使用带 condition 参数的重载方法
滥用 or()使用 and(Consumer<Wrapper>) 明确优先级
忽略 SQL 注入不要手动拼接字符串,使用 MP 提供的 API

八、LambdaQueryWrapper:类型安全升级版

LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.like(StringUtils.isNotBlank(name), User::getName, name).ge(minAge != null, User::getAge, minAge);

优点:

  • 编译期检查字段名
  • 避免魔法字符串
  • 支持方法引用

九、总结

特性描述
简洁链式调用,告别 XML
灵活动态条件,支持复杂逻辑
安全防止 SQL 注入
可维护与实体类联动,易于重构

建议

  • 简单查询用 QueryWrapper
  • 生产环境优先使用 LambdaQueryWrapper
  • 复杂 SQL 仍可用 XML 或 @Select

十、参考资料

  • MyBatis-Plus 官方文档
  • GitHub:baomidou/mybatis-plus
  • 《MyBatis-Plus 实战》


文章转载自:

http://OOkX4viO.wdpww.cn
http://YMV7wr2d.wdpww.cn
http://6ZFF1yHs.wdpww.cn
http://IZrSRSSh.wdpww.cn
http://FYRkykKk.wdpww.cn
http://6f3BLX8o.wdpww.cn
http://MoRatgSi.wdpww.cn
http://ct3onw1r.wdpww.cn
http://E0kUONEZ.wdpww.cn
http://91RhX4pZ.wdpww.cn
http://xajT6OnP.wdpww.cn
http://I3QAHvaJ.wdpww.cn
http://o6RtuLnv.wdpww.cn
http://B48JvprC.wdpww.cn
http://HSnEfyV6.wdpww.cn
http://vinT9NY9.wdpww.cn
http://ALwKtUdM.wdpww.cn
http://uTAHVsr4.wdpww.cn
http://ZfEqugEb.wdpww.cn
http://EPju174S.wdpww.cn
http://If0YidtO.wdpww.cn
http://jNM0cIhb.wdpww.cn
http://UOzxSqDl.wdpww.cn
http://QegQAQE9.wdpww.cn
http://nLjt3yd2.wdpww.cn
http://cZmudp1E.wdpww.cn
http://WPotak2c.wdpww.cn
http://1LT1ONv7.wdpww.cn
http://RnuXlxJ1.wdpww.cn
http://dFCs8bbI.wdpww.cn
http://www.dtcms.com/a/374842.html

相关文章:

  • 文件的相关概念
  • 注解参数校验
  • AI 测试平台新功能揭秘:自动化测试用例运行的奥秘
  • K8s是什么
  • 开源AI智能客服与AI智能名片在S2B2C商城小程序客服管理中的应用与影响
  • Python + Vue.js:现代全栈开发的完美组合
  • netty-scoket.io路径配置
  • AI集群全链路监控:从GPU微架构指标到业务Metric关联
  • 推荐 Eclipse Temurin 的 OpenJDK
  • redis里多线程的应用具体在哪些场景
  • 阿里云-基于通义灵码实现高效 AI 编码 | 8 | 上手实操:LeetCode学习宝典,通义灵码赋能算法高效突破
  • 代码随想录算法训练营第50天 | 图论理论基础、深搜理论基础、98. 所有可达路径、广搜理论基础
  • Gradio全解11——Streaming:流式传输的视频应用(3)——YOLO系列模型技术架构与实战
  • WPF应用程序中的异常处理
  • openEuler2403安装部署Prometheus和Grafana
  • PyCharm 连接 AutoDL 远程服务器
  • 智能AI汽车电子行业,EMS应用相关问题
  • Linux随记(二十三 )
  • 【文献速递】基于minigene技术解析PTBP3介导IL-18可变剪接的分子机制
  • 排序---快速排序(Quick Sort)
  • 开源鸿蒙北向框架开发:系统服务理论详解
  • C/C++---动态内存管理(new delete)
  • Ubuntu系统安全合规配置
  • Chrome 核心事件循环揭秘:TaskSequenceManager 与 MessagePump 的设计与实现
  • Perforce QAC 2025.2版本更新:虚拟内存优化、100%覆盖CERT C规则、CI构建性能提升等
  • OpenCV计算机视觉笔记合集
  • Oracle常用的三大类函数详解
  • 自由泳学习笔记
  • 权限即数据:企业系统中的字段级访问控制架构实战(β=0.6)
  • 研学旅游产品设计实训室:赋能产品落地,培养实用人才