Mybatis-plus进阶篇(一)

[toc]

一.条件构造器

MyBatis-Plus 提供了一套强大的条件构造器(Wrapper),用于构建复杂的数据库查询条件。Wrapper 类允许开发者以链式调用的方式构造查询条件,无需编写繁琐的 SQL 语句,从而提高开发效率并减少 SQL 注入的风险。

在 MyBatis-Plus 中,Wrapper 类是构建查询和更新条件的核心工具。以下是主要的 Wrapper 类及其功能:

  1. AbstractWrapper:这是一个抽象基类,提供了所有 Wrapper 类共有的方法和属性。它定义了条件构造的基本逻辑,包括字段(column)、值(value)、操作符(condition)等。所有的 QueryWrapper、UpdateWrapper、LambdaQueryWrapper 和 LambdaUpdateWrapper 都继承自 AbstractWrapper。

  2. QueryWrapper:专门用于构造查询条件,支持基本的等于、不等于、大于、小于等各种常见操作。它允许你以链式调用的方式添加多个查询条件,并且可以组合使用 and 和 or 逻辑。

  3. UpdateWrapper:用于构造更新条件,可以在更新数据时指定条件。与 QueryWrapper 类似,它也支持链式调用和逻辑组合。使用 UpdateWrapper 可以在不创建实体对象的情况下,直接设置更新字段和条件。

  4. LambdaQueryWrapper:这是一个基于 Lambda 表达式的查询条件构造器,它通过 Lambda 表达式来引用实体类的属性,从而避免了硬编码字段名。这种方式提高了代码的可读性和可维护性,尤其是在字段名可能发生变化的情况下。

  5. LambdaUpdateWrapper:类似于 LambdaQueryWrapper,LambdaUpdateWrapper 是基于 Lambda 表达式的更新条件构造器。它允许你使用 Lambda 表达式来指定更新字段和条件,同样避免了硬编码字段名的问题。

二.功能详解

MyBatis-Plus 的 Wrapper 类是构建复杂查询和更新条件的关键工具。它允许开发者以链式调用的方式构造 SQL 的 WHERE 子句,提供了极大的灵活性和便利性。

  1. 条件判断:Wrapper 方法通常接受一个 boolean 类型的参数,用于决定是否将该条件加入到最终的 SQL 中。例如:

    1
    2
    queryWrapper.like(StringUtils.isNotBlank(name), Entity::getName, name)
    .eq(age != null && age >= 0, Entity::getAge, age);
  2. 默认行为:如果某个方法没有显式提供 boolean 类型的参数,则默认为 true,即条件总是会被加入到 SQL 中。

  3. 泛型参数:Wrapper 类是泛型类,其中 Param 通常指的是 Wrapper 的子类实例,如 QueryWrapper、UpdateWrapper 等。

  4. 字段引用:在 LambdaWrapper 中,R 代表的是一个函数,用于引用实体类的属性,例如 Entity::getId。而在普通 Wrapper 中,R 代表的是数据库字段名。

  5. 字段名注意事项:当 R 具体类型为 String 时,表示的是数据库字段名,而不是实体类数据字段名。如果字段名是数据库关键字,需要使用转义符包裹。

  6. 集合参数:如果方法的参数是 Map 或 List,当它们为空时,对应的 SQL 条件不会被加入到最终的 SQL 中。

  7. 学习资源:对于不熟悉的函数式编程概念,可以参考学习资源进行学习。

QueryWrapper(LambdaQueryWrapper) 和 UpdateWrapper(LambdaUpdateWrapper) 的父类
用于生成 sql 的 where 条件, entity 属性也用于生成 sql 的 where 条件
注意:entity 生成的 where 条件与 使用各个 api 生成的 where 条件没有任何关联行为

1. allEq

allEq 方法是 MyBatis-Plus 中用于构建查询条件的方法之一,它允许我们通过一个 Map 来设置多个字段的相等条件。

使用范围

QueryWrapper
LambdaQueryWrapper
UpdateWrapper
LambdaUpdateWrapper

方法签名:

1
2
3
4
5
6
7
8
9
// 设置所有字段的相等条件,如果字段值为null,则根据null2IsNull参数决定是否设置为IS NULL
allEq(Map<String, Object> params)
allEq(Map<String, Object> params, boolean null2IsNull)
allEq(boolean condition, Map<String, Object> params, boolean null2IsNull)

// 设置所有字段的相等条件,通过filter过滤器决定哪些字段应该被包含,如果字段值为null,则根据null2IsNull参数决定是否设置为IS NULL
allEq(BiPredicate<String, Object> filter, Map<String, Object> params)
allEq(BiPredicate<String, Object> filter, Map<String, Object> params, boolean null2IsNull)
allEq(boolean condition, BiPredicate<String, Object> filter, Map<String, Object> params, boolean null2IsNull)

参数说明

params:一个 Map,其中 key 是数据库字段名,value 是对应的字段值。
null2IsNull:如果设置为 true,当 Map 中的 value 为 null 时,会调用 isNull 方法;如果设置为 false,则会忽略 value 为 null 的键值对。
filter:一个 BiPredicate,用于过滤哪些字段应该被包含在查询条件中。
condition:一个布尔值,用于控制是否应用这些条件。

示例

普通 Wrapper (QueryWrapper):

1
2
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.allEq(Map.of("id", 1, "name", "老王", "age", null));

Lambda Wrapper (LambdaQueryWrapper):

1
2
LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.allEq(Map.of("id", 1, "name", "老王", "age", null));

带过滤器的普通 Wrapper (QueryWrapper):

1
2
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.allEq((field, value) -> field.contains("a"), Map.of("id", 1, "name", "老王", "age", null));

带过滤器的 Lambda Wrapper (LambdaQueryWrapper):

1
2
LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.allEq((field, value) -> field.contains("a"), Map.of("id", 1, "name", "老王", "age", null));

生成的 SQL:

1
2
3
4
5
-- 普通 Wrapper 和 Lambda Wrapper 生成的 SQL 相同
SELECT * FROM user WHERE id = 1 AND name = '老王' AND age IS NULL

-- 带过滤器的普通 Wrapper 和 Lambda Wrapper 生成的 SQL 相同
SELECT * FROM user WHERE name = '老王' AND age IS NULL