Wrapper体系中的condition参数

Wrapper体系中的condition参数

Wrapper体系中的condition参数是什么

condition 是 MyBatis-Plus 核心组件 Wrapper 体系中所有条件构建方法的可选布尔型入参,也是实现条件动态生效的核心控制开关,用于决定当前条件是否被解析并加入最终 SQL。

为什么需要condition参数

在基于 MyBatis 的持久层开发过程中,动态组装 SQL 条件是高频场景,前端传入的查询、更新等动态条件往往具备可选性,若直接无条件拼接所有条件至 SQL 语句中,会因参数为空值引发 SQL 语法规范的语法错误或逻辑错误。

为解决动态条件组装问题,传统 MyBatis 需在 XML 映射文件或注解中通过 <if> 标签嵌套实现条件判断,该方式不仅导致代码冗余、维护成本高,还将动态条件逻辑分散在 SQL 层与 Java 业务层,不符合分层设计原则。

而 MyBatis-Plus 的核心组件 Wrapper 条件构造器体系中设计了 condition 核心可选布尔型入参,该参数可直接在 Java 代码层通过布尔值精准控制单个条件方法是否被解析并加入最终生成的 SQL 语句中。当 condition 为 true 时,对应条件会被拼接至 SQL 的 WHERE/SET 子句,当 condition 为 false 时,该条件会被直接忽略。这一机制既规避了 SQL 语法和逻辑错误,又将动态条件控制逻辑统一体现至 Java 代码层,大幅简化动态 SQL 开发流程,提升代码可维护性与分层合理性。

condition参数的重载方法设计

condition 参数的重载方法设计是 MyBatis-Plus 为兼顾默认生效和动态控制、以及适配多场景而制定的分层重载策略,核心围绕是否携带 condition 参数构建两类重载分支,同时让所有条件方法遵循统一的重载规则,兼顾易用性、扩展性与 API 一致性。

MyBatis-Plus 为所有核心条件构造方法统一设计了两类重载形式,且该设计覆盖普通构造器(QueryWrapper/UpdateWrapper)和 Lambda 构造器(LambdaQueryWrapper/LambdaUpdateWrapper):

  • 无 condition 参数的重载版本:方法仅接收列名(普通构造器)/ Lambda 列引用(Lambda 构造器)和值,默认内置 condition = true,调用后条件必然被解析并加入 SQL,适用于必选条件场景;
  • 带 condition 参数的重载版本:在无 condition 版本基础上新增布尔型 condition 入参,条件是否被解析、加入 SQL 由该参数的布尔值决定,适用于可选 / 动态条件场景。

condition的典型使用场景与示例

情况1:动态条件查询的基础实现方式

java 复制代码
    @Test
    public void test12() {
        String name = null;
        Integer ageBegin = 10;
        Integer ageEnd = 24;
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        if(StringUtils.isNotBlank(name)){
            queryWrapper.like("name","a");
        }
        if(ageBegin != null){
            queryWrapper.ge("age", ageBegin);
        }
        if(ageEnd != null){
            queryWrapper.le("age", ageEnd);
        }
        List<User> users = userMapper.selectList(queryWrapper);
        users.forEach(System.out::println);
    }

这是动态条件查询的基础实现方式,通过 if 语句逐个判断参数有效性,仅当参数有效时,才调用 QueryWrapper 的条件方法拼接 WHERE 子句。

需要注意 StringUtils.isNotBlank 的导包:需确保导入的是 org.apache.commons.lang3.StringUtils(需引入 commons-lang3 依赖)或 org.springframework.util.StringUtils(Spring 项目自带),避免导包错误;以及需要注意的是条件连接符,MP 的 QueryWrapper 默认用 AND 连接多个条件,若需要 OR 逻辑需显式调用 or() 方法。

拼接的 sql 语句为:

sql 复制代码
SELECT id,name,age,email FROM user WHERE (age >= ? AND age <= ?)

情况2:condition实现动态筛选条件

java 复制代码
    @Test
    public void test12UseCondition() {
        String name = null;
        Integer ageBegin = 10;
        Integer ageEnd = 24;
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .like(StringUtils.isNotBlank(name), "name", "a")
                .ge(ageBegin != null, "age", ageBegin)
                .le(ageEnd != null, "age", ageEnd);
        List<User> users = userMapper.selectList(queryWrapper);
        users.forEach(System.out::println);
    }

和情况1的区别是,情况2相当于将判断条件移至方法的第一个参数位置

基于动态参数(name 为空、ageBegin/ageEnd 有值)构建查询条件:

仅当 name 非空时,添加 name 模糊匹配 'a'的条件;

仅当 ageBegin 非空时,添加 age >= ageBegin 的条件;

仅当 ageEnd 非空时,添加 age <= ageEnd 的条件;

拼接的 sql 语句为:

sql 复制代码
SELECT id,name,age,email FROM user WHERE (age >= ? AND age <= ?)

针对不同类型参数的 非null / 非空串 判断是 condition 最核心的使用场景:

字符串 非 null 且非空串:StringUtils.isNotBlank(str)

数值类型 非 null:num != null

集合 非 null 且非空:CollectionUtils.isNotEmpty(collection)

情况3:动态条件更新的基础实现方式

java 复制代码
    @Test
    public void test13() {
        Long userId = 1L;
        String name = null;
        Integer age = 25;
        String email = "new@123.com";
        UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", userId);
        if (StringUtils.isNotBlank(name)) {
            updateWrapper.set("name", name);
        }
        if (age != null) {
            updateWrapper.set("age", age);
        }
        if (StringUtils.isNotBlank(email)) {
            updateWrapper.set("email", email);
        }
        userMapper.update(null, updateWrapper);
    }

这是动态条件更新的基础实现方式,通过 if 语句逐个判断参数有效性,仅当参数有效时,才调用 UpdateWrapper 的条件方法拼接 WHERE 子句。

组装的 sql 语句为:

sql 复制代码
UPDATE user SET age=?,email=? WHERE (id = ?)

情况4:condition实现动态更新

java 复制代码
    @Test
    public void test13Update() {
        Long userId = 1L;
        String name = null;
        Integer age = 25;
        String email = "new@123.com";
        UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
        updateWrapper
                .eq("id", userId)
                .set(StringUtils.isNotBlank(name), "name", name)
                .set(age != null, "age", age)
                .set(StringUtils.isNotBlank(email), "email", email);
        userMapper.update(null, updateWrapper);
    }

基于动态参数(name 为空、id、age、email 有值)构建动态更新条件:

指定更新 ID 为 1 的用户信息

仅当 name 非空时,更新其 name 字段;

仅当 age 非空时,更新其 age 字段;

仅当 email 非空时,更新其 email 字段;

组装的 sql 语句为:

sql 复制代码
UPDATE user SET age=?,email=? WHERE (id = ?)

情况5:多条件动态查询

java 复制代码
    @Test
    public void test16(){
        String name = "张";
        Integer age = 25;
        Long userId = 1L;
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.and(w -> w.gt(age != null, User::getAge, age)
                .like(StringUtils.isNotBlank(name), User::getName, name))
                .or(w -> w.eq(userId != null, User::getId, userId));
        List<User> users = userMapper.selectList(wrapper);
        users.forEach(System.out::println);
    }

查找年龄> 25 且姓名含张,或 ID=1 的用户

组装的 sql 语句为:

sql 复制代码
SELECT id,name,age,email FROM user WHERE ((age > ? AND name LIKE ?) OR (id = ?))
相关推荐
雨中飘荡的记忆7 小时前
Spring状态机深度解析
java·后端·spring
BBB努力学习程序设计7 小时前
Java记录类(Records)与数据建模革命:从POJO到不可变数据的范式转变
java
月屯7 小时前
Pandoc 之--pdf-engine
java·开发语言·pdf
10km7 小时前
java: HashMap.merge 的 Null 值陷阱:为什么 Stream API 会抛出 NPE
java·stream·hashmap·merge
晨星3347 小时前
使用 IntelliJ IDEA 轻松连接 Java 与 MySQL 8 数据库
java·开发语言·数据库
睡觉早点7 小时前
IntelliJ IDEA下载安装过程(含Java环境搭建)
java·ide·jdk·maven·intellij-idea
李少兄7 小时前
IntelliJ IDEA Maven 工具栏消失怎么办?
java·maven·intellij-idea
草酸艾司西酞普兰7 小时前
idea中使用Qoder插件
java·ide·intellij-idea