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

MyBatis-Plus 条件构造器(Wrapper)全解析

一、Wrapper 体系介绍

Wrapper 是 MyBatis-Plus 中用于构建查询条件的抽象类,其继承结构如下:

  • Wrapper:条件构造抽象类,最顶端父类
  • AbstractWrapper:用于查询条件封装,生成 SQL 的 WHERE 条件
    • QueryWrapper:查询条件封装
    • UpdateWrapper:更新条件封装
  • AbstractLambdaWrapper:使用 Lambda 语法构建条件
    • LambdaQueryWrapper:Lambda 风格的查询 Wrapper
    • LambdaUpdateWrapper:Lambda 风格的更新 Wrapper

核心区别

  • QueryWrapper/UpdateWrapper:通过字符串指定字段名
  • LambdaQueryWrapper/LambdaUpdateWrapper:通过 Lambda 表达式指定字段(User::getName),避免硬编码,更安全

二、QueryWrapper 实战

QueryWrapper 主要用于构建查询条件,以下是常见用法示例:

1. 组装查询条件

@Test

public void testQueryWrapper1() {

// 查询年龄大于20且邮箱不为空的用户

QueryWrapper<User> queryWrapper = new QueryWrapper<>();

queryWrapper.gt("age", 20) // 年龄>20

.isNotNull("email"); // 邮箱不为空

List<User> userList = userMapper.selectList(queryWrapper);

userList.forEach(System.out::println);

}

2. 组装排序条件

@Test

public void testQueryWrapper2() {

// 查询所有用户,按年龄降序排列,若年龄相同则按id升序排列

QueryWrapper<User> queryWrapper = new QueryWrapper<>();

queryWrapper.orderByDesc("age") // 按年龄降序

.orderByAsc("id"); // 按id升序

List<User> userList = userMapper.selectList(queryWrapper);

userList.forEach(System.out::println);

}

3. 组装删除条件

@Test

public void testQueryWrapper3() {

// 删除邮箱为空的用户

QueryWrapper<User> queryWrapper = new QueryWrapper<>();

queryWrapper.isNull("email"); // 邮箱为空

int result = userMapper.delete(queryWrapper);

System.out.println("受影响的行数:" + result);

}

4. 组装 select 子句(指定查询字段)

@Test

public void testQueryWrapper5() {

// 只查询id、name和age字段

QueryWrapper<User> queryWrapper = new QueryWrapper<>();

queryWrapper.select("id", "name", "age") // 指定查询的字段

.gt("age", 20); // 年龄>20

List<User> userList = userMapper.selectList(queryWrapper);

userList.forEach(System.out::println);

}

5. 实现子查询

@Test

public void testQueryWrapper6() {

// 查询id小于等于3的用户信息(使用子查询)

QueryWrapper<User> queryWrapper = new QueryWrapper<>();

queryWrapper.inSql("id", "select id from user where id <= 3");

List<User> userList = userMapper.selectList(queryWrapper);

userList.forEach(System.out::println);

}

三、UpdateWrapper 实战

UpdateWrapper 专门用于构建更新操作的条件,支持更灵活的 SET 语句构建:

1. 基本更新示例

@Test

public void testUpdateWrapper1() {

// 将名字中包含"张"的用户年龄改为25,邮箱改为zhang@example.com

UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();

updateWrapper.like("name", "张") // 条件:name包含"张"

.set("age", 25) // 设置age=25

.set("email", "zhang@example.com"); // 设置email

int result = userMapper.update(null, updateWrapper);

System.out.println("受影响的行数:" + result);

}

2. 复杂条件更新

@Test

public void testUpdateWrapper2() {

// 年龄小于20或邮箱为空的用户,年龄改为22

UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();

updateWrapper.lt("age", 20)

.or()

.isNull("email")

.set("age", 22);

int result = userMapper.update(null, updateWrapper);

System.out.println("受影响的行数:" + result);

}

四、条件判断(condition)

在实际开发中,查询条件往往来自用户输入,具有不确定性。我们需要根据用户是否输入来动态组装条件,避免无效条件影响查询结果。

传统思路(繁琐)

@Test

public void testCondition1() {

// 可能为null的查询条件(用户输入)

String username = null; // 用户未输入用户名

Integer ageBegin = 10; // 最小年龄

Integer ageEnd = 24; // 最大年龄

QueryWrapper<User> queryWrapper = new QueryWrapper<>();

// 仅当username不为空时才添加模糊查询

if (StringUtils.isNotBlank(username)) {

queryWrapper.like("name", username);

}

// 仅当ageBegin不为空时才添加大于等于条件

if (ageBegin != null) {

queryWrapper.ge("age", ageBegin);

}

// 仅当ageEnd不为空时才添加小于等于条件

if (ageEnd != null) {

queryWrapper.le("age", ageEnd);

}

List<User> userList = userMapper.selectList(queryWrapper);

userList.forEach(System.out::println);

}

优化思路(使用 condition 参数)

MyBatis-Plus 的条件方法提供了带condition参数的重载方法,可简化代码:

@Test

public void testCondition2() {

String username = null;

Integer ageBegin = 10;

Integer ageEnd = 24;

QueryWrapper<User> queryWrapper = new QueryWrapper<>();

// condition为true时才添加该条件

queryWrapper.like(StringUtils.isNotBlank(username), "name", username)

.ge(ageBegin != null, "age", ageBegin)

.le(ageEnd != null, "age", ageEnd);

List<User> userList = userMapper.selectList(queryWrapper);

userList.forEach(System.out::println);

}

五、LambdaQueryWrapper(推荐)

LambdaQueryWrapper 使用 Lambda 表达式指定字段,避免字符串硬编码,能在编译期发现字段错误,更安全:

@Test

public void testLambdaQueryWrapper() {

// 定义可能为null的查询条件

String username = "a";

Integer ageBegin = 10;

Integer ageEnd = 24;

LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();

// 条件判断+Lambda表达式

queryWrapper.like(StringUtils.isNotBlank(username), User::getName, username)

.ge(ageBegin != null, User::getAge, ageBegin)

.le(ageEnd != null, User::getAge, ageEnd);

List<User> userList = userMapper.selectList(queryWrapper);

userList.forEach(System.out::println);

}

六、LambdaUpdateWrapper(推荐)

LambdaUpdateWrapper 同样使用 Lambda 表达式,适合构建更新条件:

@Test

public void testLambdaUpdateWrapper() {

// 将名字中包含"a",且年龄小于24或邮箱为空的用户,年龄改为18,邮箱改为user@qcby.com

LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();

updateWrapper.like(User::getName, "a")

.and(i -> i.lt(User::getAge, 24).or().isNull(User::getEmail)) // 嵌套条件

.set(User::getAge, 18)

.set(User::getEmail, "user@qcby.com");

int result = userMapper.update(null, updateWrapper);

System.out.println("受影响的行数:" + result);

}

七、Wrapper 使用总结

Wrapper 类型

特点

适用场景

QueryWrapper

字符串指定字段

简单查询,字段名不易出错的场景

UpdateWrapper

支持 SET 语句构建

复杂更新操作

LambdaQueryWrapper

Lambda 表达式指定字段,编译期检查

复杂查询,追求类型安全

LambdaUpdateWrapper

Lambda 表达式指定字段,支持复杂条件

复杂更新,追求类型安全

http://www.dtcms.com/a/301238.html

相关文章:

  • docker in docker - 在docker容器中使用宿主机的docker
  • mac电脑安装docker图文教程
  • Java面试全栈通关:从微服务到AI的技术深度解析
  • [10月考试] C
  • Java面试全攻略:Spring生态与微服务架构实战
  • LangChain实现RAG
  • [2025CVPR-图象超分辨方向]DORNet:面向退化的正则化网络,用于盲深度超分辨率
  • 马尔可夫链
  • 设计模式(十三)结构型:代理模式详解
  • Python 使用 asyncio 包处理并 发(避免阻塞型调用)
  • 图像智能识别算法记录
  • 动态规划 (Dynamic Programming) 算法概念-Python示例
  • Leetcode——287. 寻找重复数
  • SignalR 全解析:核心原理、适用场景与 Vue + .NET Core 实战
  • 工业控制系统安全之 Modbus 协议中间人攻击(MITM)分析与防范
  • 全面理解JVM虚拟机
  • RS485转profinet网关如何让JRT激光测距传感器开启自动模式连续测量模式
  • 淘宝获取店铺订单信息操作指南
  • Python爬虫入门:从零开始抓取网页数据
  • 每日一讲——Podman
  • 分布式事务-MQ事务消息学习与落地方案
  • 前端面试专栏-前沿技术:32.AI辅助开发工具应用
  • 0-1BFS(双端队列,洛谷P4667 [BalticOI 2011] Switch the Lamp On 电路维修 (Day1)题解)
  • 用 Flask 打造宠物店线上平台:从 0 到 1 的全栈开发实践
  • 电商项目_核心业务_数据归档
  • esp32-使用虚拟机开发-部署esp32的linux的环境
  • 如何关闭浏览器的迅雷图标 - 去掉浏览器左下角的迅雷图标 - chrome - 关闭迅雷检测
  • C/C++核心知识点详解
  • 剑指offer——搜索算法:数字序列中某一位的数字
  • Python操作Excel文件完整指南