Springboot的Mybatis中的条件构造器

一.条件构造器是做什么的?

先看一个需求:

查询用户表中,姓名为"张三",年龄大于等于18岁的用户,并按年龄从小到大排序。

直接写SQL:

sql 复制代码
SELECT *
FROM user
WHERE name = '张三'
  AND age >= 18
ORDER BY age ASC;

使用MyBatis-Plus,可以用java代码描述这些条件:

java 复制代码
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();

wrapper.eq(User::getName, "张三")
       .ge(User::getAge, 18)
       .orderByAsc(User::getAge);

List<User> users = userMapper.selectList(wrapper);

对应关系:

|--------------------------|------------------|
| Java写法 | SQL含义 |
| eq(User::getName, "张三") | name = '张三' |
| ge(User::getAge, 18) | age >= 18 |
| orderByAsc(User::getAge) | ORDER BY age ASC |

核心理解:条件构造器负责描述条件,Mapper方法负责执行数据操作。

java 复制代码
// 只是构造条件,还没有查询数据库
wrapper.eq(User::getName, "张三");

// 调用 Mapper,才真正查询数据库
List<User> users = userMapper.selectList(wrapper);

上面的SQL是为了方便理解;实际执行时,普通条件中的值通常通过参数绑定传入。

二.MyBatis和MyBatis-Plus要分清

  • **Spring Boot:**负责应用配置、组件管理等。
  • **MyBatis:**持久层框架,支持通过 XML、注解等方式编写 SQL。
  • **MyBatis-Plus:**在 MyBatis 的基础上提供增强功能,例如通用 CRUD、条件构造器。

因此,你现在学的 QueryWrapper,准确地说属于 MyBatis-Plus。

通常 Mapper 会这样定义:

java 复制代码
@Mapper
public interface UserMapper extends BaseMapper<User> {
}

继承 BaseMapper<User> 后,就可以使用它提供的方法:

java 复制代码
userMapper.selectList(wrapper); // 根据条件查询列表
userMapper.selectCount(wrapper); // 根据条件统计数量
userMapper.delete(wrapper);     // 根据条件删除

注意:同一个条件可以用于不同操作,最终做什么取决于你调用的方法。 不要把查询条件构造器误认为只能用于查询。

三.最常见的四种条件构造器

类型 主要用途 字段写法
QueryWrapper<User> 查询条件、排序、查询字段等 "name"
LambdaQueryWrapper<User> 查询条件的 Lambda 写法 User::getName
UpdateWrapper<User> 更新条件及更新字段 "name"
LambdaUpdateWrapper<User> 更新条件及字段的 Lambda 写法 User::getName

1. QueryWrapper:使用数据库列名

java 复制代码
QueryWrapper<User> wrapper = new QueryWrapper<>();

wrapper.eq("name", "张三")
       .ge("age", 18);

这里的 "name" 和 "age" 是数据库列名。

如果实体属性是 userName,数据库列名是 user_name,一般应写:

java 复制代码
wrapper.eq("user_name", "张三");

2. LambdaQueryWrapper:使用实体的 getter

java 复制代码
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();

wrapper.eq(User::getName, "张三")
       .ge(User::getAge, 18);

User::getName 是方法引用,MyBatis-Plus 会根据实体映射信息解析出对应的数据库列。

它不是"现在调用 getter 获取某个用户的姓名",而是在这里标识要操作哪个属性对应的列。

学习和日常开发时,建议优先使用 LambdaQueryWrapper:字段更容易检查,也方便重构。

四、先掌握这些常用方法

方法 含义 SQL 示例
eq 等于 age = 18
ne 不等于 age <> 18
gt 大于 age > 18
ge 大于等于 age >= 18
lt 小于 age < 18
le 小于等于 age <= 18
like 包含某段文字 name LIKE '%张%'
between 在某个范围内,包含两端 age BETWEEN 18 AND 30
in 属于给定值集合 status IN (1, 2)
isNull 是 NULL email IS NULL
orderByAsc 升序排序 ORDER BY age ASC
orderByDesc 降序排序 ORDER BY age DESC
java 复制代码
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();

wrapper.like(User::getName, "张")
       .between(User::getAge, 18, 30)
       .eq(User::getStatus, 1)
       .orderByDesc(User::getAge);

List<User> users = userMapper.selectList(wrapper);

含义是:

查询姓名包含"张"、年龄在 18~30 岁之间、状态为 1 的用户,按年龄从大到小排序。

连续添加的普通条件,默认用 AND 连接。

这些方法返回当前构造器,因此可以连续调用,也就是"链式调用"。

五、特别重要:动态条件

实际项目里,用户可能只输入姓名,也可能只输入年龄,还可能什么都不输入。

java 复制代码
String name = null;
Integer minAge = 18;

我们希望:

  • 姓名有内容,才添加姓名条件。
  • 最小年龄不为 null,才添加年龄条件。

可以这样写:

java 复制代码
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();

wrapper.like(
           StringUtils.hasText(name),
           User::getName,
           name
       )
       .ge(
           minAge != null,
           User::getAge,
           minAge
       );

List<User> users = userMapper.selectList(wrapper);

这里使用的是 Spring 的工具类:

java 复制代码
import org.springframework.util.StringUtils;

重点看这个结构:

java 复制代码
eq(boolean condition, 字段, 值)

第一个参数决定:是否把这一条条件加进去。

java 复制代码
wrapper.eq(true, User::getStatus, 1);  // 添加条件
wrapper.eq(false, User::getStatus, 1); // 不添加条件

所以前面的示例只会添加:

java 复制代码
WHERE age >= 18

不会添加姓名条件。

注意:不要认为传入 null 就一定自动忽略条件。 判断数据库字段是不是 NULL,应使用 isNull();决定是否添加查询条件,应使用布尔参数或 if。

六、现在先记住这条流程

创建构造器

↓

添加条件、排序等

↓

把构造器传给 Mapper 方法

↓

MyBatis-Plus 生成并执行 SQL

↓

获取结果

相关推荐
倔强的石头_1 小时前
列存储到底快在哪 在金仓KES上把原理和实操跑了一遍
数据库
WikiLeake1 小时前
一个健壮且灵活的大语言模型(LLM)API 配置加载器
数据库·人工智能
瑞克-桑切斯3 小时前
企业生产环境:https部署+nginx高可用(业务不中断)
linux·服务器·数据库
zyseo811 小时前
谷歌SEO 准首页词挖掘脚本:找出排在第 8-20 名的隐藏流量
大数据·数据库·人工智能
xiaogai_gai13 小时前
仅查询策略实战:从金蝶云·星空旗舰版定时拉取收料通知单
大数据·数据库·python
数据工匠老o14 小时前
异构数据库DDL同步:260条链路的结构变更自动适配方案
数据库·架构
这个DBA有点耶14 小时前
银行业市占率最高的国产数据库是谁?先搞清楚“市占率”的四种口径
数据库·程序员·架构
用户62799471826215 小时前
南大通用GBase 8a之基于审计日志的冷温热数据分析
数据库