MyBatis-Plus 提供了一套强大的条件构造器(Wrapper),用于构建复杂的数据库查询条件。Wrapper 类允许开发者以链式调用的方式构造查询条件,无需编写繁琐的 SQL 语句,从而提高开发效率并减少 SQL 注入的风险。
在 MyBatis-Plus 中,Wrapper 类是构建查询和更新条件的核心工具。以下是主要的 Wrapper 类及其功能:
AbstractWrapper:这是一个抽象基类,提供了所有 Wrapper 类共有的方法和属性。它定义了条件构造的基本逻辑,包括字段(column)、值(value)、操作符(condition)等。所有的 QueryWrapper、UpdateWrapper、LambdaQueryWrapper 和 LambdaUpdateWrapper 都继承自 AbstractWrapper。
QueryWrapper:专门用于构造查询条件,支持基本的等于、不等于、大于、小于等各种常见操作。它允许你以链式调用的方式添加多个查询条件,并且可以组合使用 and
和 or
逻辑。
UpdateWrapper:用于构造更新条件,可以在更新数据时指定条件。与 QueryWrapper 类似,它也支持链式调用和逻辑组合。使用 UpdateWrapper 可以在不创建实体对象的情况下,直接设置更新字段和条件。
LambdaQueryWrapper:这是一个基于 Lambda 表达式的查询条件构造器,它通过 Lambda 表达式来引用实体类的属性,从而避免了硬编码字段名。这种方式提高了代码的可读性和可维护性,尤其是在字段名可能发生变化的情况下。
LambdaUpdateWrapper:类似于 LambdaQueryWrapper,LambdaUpdateWrapper 是基于 Lambda 表达式的更新条件构造器。它允许你使用 Lambda 表达式来指定更新字段和条件,同样避免了硬编码字段名的问题。
条件判断:Wrapper 方法通常接受一个
boolean
类型的参数,用于决定是否将该条件加入到最终的 SQL 中。例如:ueryWrapper.like(StringUtils.isNotBlank(name), Entity::getName, name).eq(age != null && age >= 0, Entity::getAge, age);
默认行为:如果某个方法没有显式提供
boolean
类型的参数,则默认为true
,即条件总是会被加入到 SQL 中。泛型参数:Wrapper 类是泛型类,其中
Param
通常指的是 Wrapper 的子类实例,如 QueryWrapper、UpdateWrapper 等。字段引用:在 LambdaWrapper 中,
R
代表的是一个函数,用于引用实体类的属性,例如Entity::getId
。而在普通 Wrapper 中,R
代表的是数据库字段名。字段名注意事项:当
R
具体类型为String
时,表示的是数据库字段名,而不是实体类数据字段名。如果字段名是数据库关键字,需要使用转义符包裹。集合参数:如果方法的参数是
Map
或List
,当它们为空时,对应的 SQL 条件不会被加入到最终的 SQL 中。
RPC(Remote Procedure Call即远程过程调用) 调用中的 Wrapper:不支持也不赞成在 RPC 调用中传输 Wrapper 对象。Wrapper 对象通常包含大量信息,不适合作为传输对象。正确的做法是定义一个 DTO(数据传输对象)进行传输,然后在被调用方根据 DTO 执行相应的操作。
维护性:避免在 Controller 层使用 Map 接收值,这种做法虽然开发时方便,但会给后续的维护带来困难。
问题反馈:不接受任何关于 RPC 传输 Wrapper 报错相关的 issue 或 pr。
安全性:
QueryWrapper
UpdateWrapper
字段部分,如有允许前端传入 SQL 片段
这可能会导致SQL 注入风险
需要校验,更多查看
Wrapper 实例不是线程安全的,因此建议在每次使用时创建新的 Wrapper 实例。这样可以避免多线程环境下的数据竞争和潜在的错误。
allEq
方法是 MyBatis-Plus 中用于构建查询条件的方法之一,它允许我们通过一个 Map
来设置多个字段的相等条件。
QueryWrapper
LambdaQueryWrapper
UpdateWrapper
LambdaUpdateWrapper
/**
* map 所有非空属性等于 =
*
* @param params map 类型的参数, key 是字段名, value 是字段值
* @return children
*/
default Children allEq(Map params) {
return allEq(params, true);
}
/**
* map 所有非空属性等于 =
*
* @param params map 类型的参数, key 是字段名, value 是字段值
* @param null2IsNull 是否参数为 null 自动执行 isNull 方法, false 则忽略这个字段
* @return children
*/
default Children allEq(Map params, boolean null2IsNull) {
return allEq(true, params, null2IsNull);
}
/**
* map 所有非空属性等于 =
*
* @param condition 执行条件
* @param params map 类型的参数, key 是字段名, value 是字段值
* @param null2IsNull 是否参数为 null 自动执行 isNull 方法, false 则忽略这个字段
* @return children
*/
Children allEq(boolean condition, Map params, boolean null2IsNull);
/**
* 字段过滤接口,传入多参数时允许对参数进行过滤
*
* @param filter 返回 true 来允许字段传入比对条件中
* @param params map 类型的参数, key 是字段名, value 是字段值
* @return children
*/
default Children allEq(BiPredicate filter, Map params) {
return allEq(filter, params, true);
}
/**
* 字段过滤接口,传入多参数时允许对参数进行过滤
*
* @param filter 返回 true 来允许字段传入比对条件中
* @param params map 类型的参数, key 是字段名, value 是字段值
* @param null2IsNull 是否参数为 null 自动执行 isNull 方法, false 则忽略这个字段
* @return children
*/
default Children allEq(BiPredicate filter, Map params, boolean null2IsNull) {
return allEq(true, filter, params, null2IsNull);
}
/**
* 字段过滤接口,传入多参数时允许对参数进行过滤
*
* @param condition 执行条件
* @param filter 返回 true 来允许字段传入比对条件中
* @param params map 类型的参数, key 是字段名, value 是字段值
* @param null2IsNull 是否参数为 null 自动执行 isNull 方法, false 则忽略这个字段
* @return children
*/
Children allEq(boolean condition, BiPredicate filter, Map params, boolean null2IsNull);
普通 Wrapper (QueryWrapper):
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.allEq(Map.of("id", 1, "name", "老王", "age", null));
Lambda Wrapper (LambdaQueryWrapper):
LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.allEq(Map.of("id", 1, "name", "老王", "age", null));
带过滤器的普通 Wrapper (QueryWrapper):
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.allEq((field, value) -> field.contains("a"), Map.of("id", 1, "name", "老王", "age", null));
带过滤器的 Lambda Wrapper (LambdaQueryWrapper):
LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.allEq((field, value) -> field.contains("a"), Map.of("id", 1, "name", "老王", "age", null));
生成的 SQL
-- 普通 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
eq
方法是 MyBatis-Plus 中用于构建查询条件的基本方法之一,它用于设置单个字段的相等条件。
QueryWrapper
LambdaQueryWrapper
UpdateWrapper
LambdaUpdateWrapper
/**
* 等于 =
*
* @param column 字段
* @param val 值
* @return children
*/
default Children eq(R column, Object val) {
return eq(true, column, val);
}
/**
* 等于 =
*
* @param condition 执行条件
* @param column 字段
* @param val 值
* @return children
*/
Children eq(boolean condition, R column, Object val);
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.eq("name", "老王");
LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(User::getName, "老王");
生成的 SQL
-- Wrapper 和 Lambda Wrapper 生成的 SQL 相同
SELECT * FROM user WHERE name = '老王'
ne
方法是 MyBatis-Plus 中用于构建查询条件的基本方法之一,它用于设置单个字段的不相等条件。
QueryWrapper
LambdaQueryWrapper
UpdateWrapper
LambdaUpdateWrapper
/**
* 不等于 <>
*
* @param column 字段
* @param val 值
* @return children
*/
default Children ne(R column, Object val) {
return ne(true, column, val);
}
/**
* 不等于 <>
*
* @param condition 执行条件
* @param column 字段
* @param val 值
* @return children
*/
Children ne(boolean condition, R column, Object val);
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.ne("name", "老王");
Lambda Wrapper (LambdaQueryWrapper):
LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.ne(User::getName, "老王");
生成的 SQL
-- Wrapper 和 Lambda Wrapper 生成的 SQL 相同
SELECT * FROM user WHERE name <> '老王'
gt
方法是 MyBatis-Plus 中用于构建查询条件的基本方法之一,它用于设置单个字段的大于条件。
QueryWrapper
LambdaQueryWrapper
UpdateWrapper
LambdaUpdateWrapper
/**
* 大于 >
*
* @param column 字段
* @param val 值
* @return children
*/
default Children gt(R column, Object val) {
return gt(true, column, val);
}
/**
* 大于 >
*
* @param condition 执行条件
* @param column 字段
* @param val 值
* @return children
*/
Children gt(boolean condition, R column, Object val);
Wrapper (QueryWrapper):
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.gt("age", 18);
Lambda Wrapper (LambdaQueryWrapper):
LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.gt(User::getAge, 18);
生成的 SQL
-- Wrapper 和 Lambda Wrapper 生成的 SQL 相同
SELECT * FROM user WHERE age > 18
gt
方法适用于数值型字段,对于字符串等非数值型字段,使用gt
可能会导致不期望的结果或错误。- 在使用
gt
方法时,确保val
参数的类型与字段类型相匹配,以避免类型转换错误。- 如果需要根据某些条件动态添加大于条件,可以使用带有
condition
参数的重载方法。
ge
方法是 MyBatis-Plus 中用于构建查询条件的基本方法之一,它用于设置单个字段的大于等于条件。
QueryWrapper
LambdaQueryWrapper
UpdateWrapper
LambdaUpdateWrapper
/**
* 大于等于 >=
*
* @param column 字段
* @param val 值
* @return children
*/
default Children ge(R column, Object val) {
return ge(true, column, val);
}
/**
* 大于等于 >=
*
* @param condition 执行条件
* @param column 字段
* @param val 值
* @return children
*/
Children ge(boolean condition, R column, Object val);
Wrapper (QueryWrapper):
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.ge("age", 18);
Lambda Wrapper (LambdaQueryWrapper):
LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.ge(User::getAge, 18);
生成的 SQL
-- Wrapper 和 Lambda Wrapper 生成的 SQL 相同
SELECT * FROM user WHERE age >= 18
lt
方法是 MyBatis-Plus 中用于构建查询条件的基本方法之一,它用于设置单个字段的小于条件。
QueryWrapper
LambdaQueryWrapper
UpdateWrapper
LambdaUpdateWrapper
/**
* 小于 <
*
* @param column 字段
* @param val 值
* @return children
*/
default Children lt(R column, Object val) {
return lt(true, column, val);
}
/**
* 小于 <
*
* @param condition 执行条件
* @param column 字段
* @param val 值
* @return children
*/
Children lt(boolean condition, R column, Object val);
Wrapper (QueryWrapper):
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.lt("age", 18);
Lambda Wrapper (LambdaQueryWrapper):
LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.lt(User::getAge, 18);
生成的 SQL
-- Wrapper 和 Lambda Wrapper 生成的 SQL 相同
SELECT * FROM user WHERE age < 18
le
方法是 MyBatis-Plus 中用于构建查询条件的基本方法之一,它用于设置单个字段的小于等于条件。
QueryWrapper
LambdaQueryWrapper
UpdateWrapper
LambdaUpdateWrapper
/**
* 小于等于 <=
*
* @param column 字段
* @param val 值
* @return children
*/
default Children le(R column, Object val) {
return le(true, column, val);
}
/**
* 小于等于 <=
*
* @param condition 执行条件
* @param column 字段
* @param val 值
* @return children
*/
Children le(boolean condition, R column, Object val);
Wrapper (QueryWrapper):
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.le("age", 18);
Lambda Wrapper (LambdaQueryWrapper):
LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.le(User::getAge, 18);
生成的 SQL
-- Wrapper 和 Lambda Wrapper 生成的 SQL 相同
SELECT * FROM user WHERE age <= 18
between
方法是 MyBatis-Plus 中用于构建查询条件的基本方法之一,它用于设置单个字段的 BETWEEN 条件。
QueryWrapper
LambdaQueryWrapper
UpdateWrapper
LambdaUpdateWrapper
/**
* BETWEEN 值1 AND 值2
*
* @param column 字段
* @param val1 值1
* @param val2 值2
* @return children
*/
default Children between(R column, Object val1, Object val2) {
return between(true, column, val1, val2);
}
/**
* BETWEEN 值1 AND 值2
*
* @param condition 执行条件
* @param column 字段
* @param val1 值1
* @param val2 值2
* @return children
*/
Children between(boolean condition, R column, Object val1, Object val2);
普通 Wrapper (QueryWrapper):
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.between("age", 18, 30);
Lambda Wrapper (LambdaQueryWrapper):
LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.between(User::getAge, 18, 30);
生成的 SQL
-- 普通 Wrapper 和 Lambda Wrapper 生成的 SQL 相同
SELECT * FROM user WHERE age BETWEEN 18 AND 30
notBetween
方法是 MyBatis-Plus 中用于构建查询条件的另一个基本方法,它用于设置单个字段的 NOT BETWEEN 条件。
QueryWrapper
LambdaQueryWrapper
UpdateWrapper
LambdaUpdateWrapper
/**
* NOT BETWEEN 值1 AND 值2
*
* @param column 字段
* @param val1 值1
* @param val2 值2
* @return children
*/
default Children notBetween(R column, Object val1, Object val2) {
return notBetween(true, column, val1, val2);
}
/**
* NOT BETWEEN 值1 AND 值2
*
* @param condition 执行条件
* @param column 字段
* @param val1 值1
* @param val2 值2
* @return children
*/
Children notBetween(boolean condition, R column, Object val1, Object val2);
普通 Wrapper (QueryWrapper):
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.notBetween("age", 18, 30);
Lambda Wrapper (LambdaQueryWrapper):
LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.notBetween(User::getAge, 18, 30);
生成的 SQL
-- 普通 Wrapper 和 Lambda Wrapper 生成的 SQL 相同
SELECT * FROM user WHERE age NOT BETWEEN 18 AND 30
like
方法是 MyBatis-Plus 中用于构建模糊查询条件的基本方法之一,它用于设置单个字段的 LIKE 条件。
QueryWrapper
LambdaQueryWrapper
UpdateWrapper
LambdaUpdateWrapper
/**
* LIKE '%值%'
*
* @param column 字段
* @param val 值
* @return children
*/
default Children like(R column, Object val) {
return like(true, column, val);
}
/**
* LIKE '%值%'
*
* @param condition 执行条件
* @param column 字段
* @param val 值
* @return children
*/
Children like(boolean condition, R column, Object val);
普通 Wrapper (QueryWrapper):
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.like("name", "王");
Lambda Wrapper (LambdaQueryWrapper):
LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.like(User::getName, "王");
生成的 SQL
-- 普通 Wrapper 和 Lambda Wrapper 生成的 SQL 相同
SELECT * FROM user WHERE name LIKE '%王%'
默认情况下,
like
方法会在搜索值前后添加%
,实现全模糊匹配。如果需要左模糊或右模糊匹配,可以使用likeRight
或likeLeft
方法。
/**
* LIKE '%值'
*
* @param column 字段
* @param val 值
* @return children
*/
default Children likeLeft(R column, Object val) {
return likeLeft(true, column, val);
}
/**
* LIKE '%值'
*
* @param condition 执行条件
* @param column 字段
* @param val 值
* @return children
*/
Children likeLeft(boolean condition, R column, Object val);
/**
* LIKE '值%'
*
* @param column 字段
* @param val 值
* @return children
*/
default Children likeRight(R column, Object val) {
return likeRight(true, column, val);
}
/**
* LIKE '值%'
*
* @param condition 执行条件
* @param column 字段
* @param val 值
* @return children
*/
Children likeRight(boolean condition, R column, Object val);
notLike
方法是 MyBatis-Plus 中用于构建模糊查询条件的另一个基本方法,它用于设置单个字段的 NOT LIKE 条件。
QueryWrapper
LambdaQueryWrapper
UpdateWrapper
LambdaUpdateWrapper
/**
* NOT LIKE '%值%'
*
* @param column 字段
* @param val 值
* @return children
*/
default Children notLike(R column, Object val) {
return notLike(true, column, val);
}
/**
* NOT LIKE '%值%'
*
* @param condition 执行条件
* @param column 字段
* @param val 值
* @return children
*/
Children notLike(boolean condition, R column, Object val);
普通 Wrapper (QueryWrapper):
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.notLike("name", "王");
Lambda Wrapper (LambdaQueryWrapper):
LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.notLike(User::getName, "王");
生成的 SQL
-- 普通 Wrapper 和 Lambda Wrapper 生成的 SQL 相同
SELECT * FROM user WHERE name NOT LIKE '%王%'
默认情况下,
notLike
方法会在搜索值前后添加%
,实现全模糊排除。如果需要排除左模糊或排除右模糊匹配,可以使用notLikeRight
或notLikeLeft
方法。
/**
* NOT LIKE '%值'
*
* @param column 字段
* @param val 值
* @return children
*/
default Children notLikeLeft(R column, Object val) {
return notLikeLeft(true, column, val);
}
/**
* NOT LIKE '%值'
*
* @param condition 执行条件
* @param column 字段
* @param val 值
* @return children
*/
Children notLikeLeft(boolean condition, R column, Object val);
/**
* NOT LIKE '值%'
*
* @param column 字段
* @param val 值
* @return children
*/
default Children notLikeRight(R column, Object val) {
return notLikeRight(true, column, val);
}
/**
* NOT LIKE '值%'
*
* @param condition 执行条件
* @param column 字段
* @param val 值
* @return children
*/
Children notLikeRight(boolean condition, R column, Object val);
isNull
方法是 MyBatis-Plus 中用于构建查询条件的基本方法之一,它用于设置单个字段的 IS NULL 条件。
QueryWrapper
LambdaQueryWrapper
UpdateWrapper
LambdaUpdateWrapper
/**
* 字段 IS NULL
* 例: isNull("name")
*
* @param column 字段
* @return children
*/
default Children isNull(R column) {
return isNull(true, column);
}
/**
* 字段 IS NULL
* 例: isNull(true, "name")
*
* @param condition 执行条件
* @param column 字段
* @return children
*/
Children isNull(boolean condition, R column);
普通 Wrapper (QueryWrapper):
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.isNull("name");
Lambda Wrapper (LambdaQueryWrapper):
LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.isNull(User::getName);
生成的 SQL
-- 普通 Wrapper 和 Lambda Wrapper 生成的 SQL 相同
SELECT * FROM user WHERE name IS NULL
isNull
方法适用于所有类型的字段,用于查询字段值为 NULL 的记录。- 在使用
isNull
方法时,确保column
参数正确指向了数据库中的字段名或使用Lambda
表达式的字段名。
in
方法是 MyBatis-Plus 中用于构建查询条件的基本方法之一,它用于设置单个字段的 IN 条件,即字段的值在给定的集合中。
QueryWrapper
LambdaQueryWrapper
UpdateWrapper
LambdaUpdateWrapper
/**
* 字段 IN (value.get(0), value.get(1), ...)
* 例: in("id", Arrays.asList(1, 2, 3, 4, 5))
*
* 注意!当集合为 空或null 时, sql会拼接为:WHERE (字段名 IN ()), 执行时报错
* 若要在特定条件下不拼接, 可在 condition 条件中判断
*
* @param column 字段
* @param coll 数据集合
* @return children
*/
default Children in(R column, Collection> coll) {
return in(true, column, coll);
}
/**
* 字段 IN (value.get(0), value.get(1), ...)
* 例: in(true, "id", Arrays.asList(1, 2, 3, 4, 5))
*
* 注意!当集合为 空或null 时, sql会拼接为:WHERE (字段名 IN ()), 执行时报错
* 若要在特定条件下不拼接, 可在 condition 条件中判断
*
* @param condition 执行条件
* @param column 字段
* @param coll 数据集合
* @return children
*/
Children in(boolean condition, R column, Collection> coll);
/**
* 字段 IN (v0, v1, ...)
* 例: in("id", 1, 2, 3, 4, 5)
*
* 注意!当数组为 空或null 时, sql会拼接为:WHERE (字段名 IN ()), 执行时报错
* 若要在特定条件下不拼接, 可在 condition 条件中判断
*
* @param column 字段
* @param values 数据数组
* @return children
*/
default Children in(R column, Object... values) {
return in(true, column, values);
}
/**
* 字段 IN (v0, v1, ...)
* 例: in(true, "id", 1, 2, 3, 4, 5)
*
* 注意!当数组为 空或null 时, sql会拼接为:WHERE (字段名 IN ()), 执行时报错
* 若要在特定条件下不拼接, 可在 condition 条件中判断
*
* @param condition 执行条件
* @param column 字段
* @param values 数据数组
* @return children
*/
Children in(boolean condition, R column, Object... values);
普通 Wrapper (QueryWrapper):
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.in("age", Arrays.asList(1, 2, 3));
Lambda Wrapper (LambdaQueryWrapper):
LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.in(User::getAge, Arrays.asList(1, 2, 3));
生成的 SQL
-- 普通 Wrapper 和 Lambda Wrapper 生成的 SQL 相同
SELECT * FROM user WHERE age IN (1, 2, 3)
notIn
方法是 MyBatis-Plus 中用于构建查询条件的基本方法之一,它用于设置单个字段的 NOT IN 条件,即字段的值不在给定的集合中。
QueryWrapper
LambdaQueryWrapper
UpdateWrapper
LambdaUpdateWrapper
/**
* 字段 NOT IN (value.get(0), value.get(1), ...)
* 例: notIn("id", Arrays.asList(1, 2, 3, 4, 5))
*
* 注意!当集合为 空或null 时, sql会拼接为:WHERE (字段名 NOT IN ()), 执行时报错
* 若要在特定条件下不拼接, 可在 condition 条件中判断
*
* @param column 字段
* @param coll 数据集合
* @return children
*/
default Children notIn(R column, Collection> coll) {
return notIn(true, column, coll);
}
/**
* 字段 NOT IN (value.get(0), value.get(1), ...)
* 例: notIn(true, "id", Arrays.asList(1, 2, 3, 4, 5))
*
* 注意!当集合为 空或null 时, sql会拼接为:WHERE (字段名 NOT IN ()), 执行时报错
* 若要在特定条件下不拼接, 可在 condition 条件中判断
*
* @param condition 执行条件
* @param column 字段
* @param coll 数据集合
* @return children
*/
Children notIn(boolean condition, R column, Collection> coll);
/**
* 字段 NOT IN (v0, v1, ...)
* 例: notIn("id", 1, 2, 3, 4, 5)
*
* 注意!当数组为 空或null 时, sql会拼接为:WHERE (字段名 NOT IN ()), 执行时报错
* 若要在特定条件下不拼接, 可在 condition 条件中判断
*
* @param column 字段
* @param values 数据数组
* @return children
*/
default Children notIn(R column, Object... values) {
return notIn(true, column, values);
}
/**
* 字段 NOT IN (v0, v1, ...)
* 例: notIn(true, "id", 1, 2, 3, 4, 5)
*
* 注意!当数组为 空或null 时, sql会拼接为:WHERE (字段名 NOT IN ()), 执行时报错
* 若要在特定条件下不拼接, 可在 condition 条件中判断
*
* @param condition 执行条件
* @param column 字段
* @param values 数据数组
* @return children
*/
Children notIn(boolean condition, R column, Object... values);
普通 Wrapper (QueryWrapper):
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.notIn("age", Arrays.asList(1, 2, 3));
Lambda Wrapper (LambdaQueryWrapper):
LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.notIn(User::getAge, Arrays.asList(1, 2, 3));
生成的 SQL
-- 普通 Wrapper 和 Lambda Wrapper 生成的 SQL 相同
SELECT * FROM user WHERE age NOT IN (1, 2, 3)
inSql
方法是 MyBatis-Plus 中用于构建查询条件的高级方法之一,它用于设置单个字段的 IN 条件,但与 in
方法不同的是,inSql
允许你直接使用 SQL 语句来生成 IN 子句中的值集合。
QueryWrapper
LambdaQueryWrapper
UpdateWrapper
LambdaUpdateWrapper
/**
* 字段 IN ( sql语句 )
* !! sql 注入方式的 in 方法 !!
* 例1: inSql("id", "1")
* 例2: inSql("id", "select id from table where id < 3")
*
* @param column 字段
* @param sql sql语句
* @return children
*/
default Children inSql(R column, String sql) {
return inSql(true, column, sql);
}
/**
* 字段 IN ( sql语句 )
* !! sql 注入方式的 in 方法 !!
* 例1: inSql(true, "id", "1")
* 例2: inSql(true, "id", "select id from table where id < 3")
*
* @param condition 执行条件
* @param column 字段
* @param sql sql语句
* @return children
*/
Children inSql(boolean condition, R column, String sql);
普通 Wrapper (QueryWrapper):
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.inSql("age", "1,2,3,4,5,6");
Lambda Wrapper (LambdaQueryWrapper):
LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.inSql(User::getAge, "1,2,3,4,5,6");
生成的 SQL
-- 普通 Wrapper 和 Lambda Wrapper 生成的 SQL 相同
SELECT * FROM user WHERE age IN (1, 2, 3, 4, 5, 6)
使用子查询的示例:
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.inSql("id", "select id from other_table where id < 3");
生成的 SQL
SELECT * FROM user WHERE id IN (select id from other_table where id < 3)
sqlValue
参数应该是一个有效的 SQL 语句,它将直接嵌入到生成的 SQL 中,因此需要确保其安全性和正确性,应避免 SQL 由前端动态参数传入并直接引用。
notInSql
方法是 MyBatis-Plus 中用于构建查询条件的高级方法之一,它用于设置单个字段的 NOT IN 条件,但与 notIn
方法不同的是,notInSql
允许你直接使用 SQL 语句来生成 NOT IN 子句中的值集合。
QueryWrapper
LambdaQueryWrapper
UpdateWrapper
LambdaUpdateWrapper
/**
* 字段 NOT IN ( sql语句 )
* !! sql 注入方式的 not in 方法 !!
* 例1: notInSql("id", "1, 2, 3, 4, 5, 6")
* 例2: notInSql("id", "select id from table where id < 3")
*
* @param column 字段
* @param inValue sql语句 ---> 1,2,3,4,5,6 或者 select id from table where id < 3
* @return children
*/
default Children notInSql(R column, String inValue) {
return notInSql(true, column, inValue);
}
/**
* 字段 NOT IN ( sql语句 )
* !! sql 注入方式的 not in 方法 !!
* 例1: notInSql(true, "id", "1, 2, 3, 4, 5, 6")
* 例2: notInSql(true, "id", "select id from table where id < 3")
*
* @param condition 执行条件
* @param column 字段
* @param inValue sql语句 ---> 1,2,3,4,5,6 或者 select id from table where id < 3
* @return children
*/
Children notInSql(boolean condition, R column, String inValue);
普通 Wrapper (QueryWrapper):
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.notInSql("age", "1,2,3,4,5,6");
Lambda Wrapper (LambdaQueryWrapper):
LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.notInSql(User::getAge, "1,2,3,4,5,6");
生成的 SQL
-- 普通 Wrapper 和 Lambda Wrapper 生成的 SQL 相同
SELECT * FROM user WHERE age NOT IN (1, 2, 3, 4, 5, 6)
使用子查询的示例:
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.notInSql("id", "select id from other_table where id < 3");
生成的 SQL
SELECT * FROM user WHERE id NOT IN (select id from other_table where id < 3)
eqSql
方法是 MyBatis-Plus 中用于构建查询条件的高级方法之一,允许你设置一个字段等于(EQ)某个 SQL 语句的结果。这个方法特别适用于需要将字段值与子查询结果进行比较的场景。
/**
* 字段 EQ ( sql语句 )
* !! sql 注入方式的 eq 方法 !!
* 例1: eqSql("id", "1")
* 例2: eqSql("id", "select MAX(id) from table")
*
* @param column 字段
* @param sql sql语句
* @return children
* @since 3.5.6
*/
default Children eqSql(R column, String sql) {
return eqSql(true, column, sql);
}
/**
* 字段 EQ ( sql语句 )
* !! sql 注入方式的 eq 方法 !!
* 例1: eqSql("id", "1")
* 例2: eqSql("id", "select MAX(id) from table")
*
* @param condition 执行条件
* @param column 字段
* @param sql sql语句
* @return children
* @since 3.5.6
*/
Children eqSql(boolean condition, R column, String sql);
普通 Wrapper (QueryWrapper):
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.eqSql("id", "select MAX(id) from table");
Lambda Wrapper (LambdaQueryWrapper):
LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eqSql(User::getId, "select MAX(id) from table");
生成的 SQL
-- 普通 Wrapper 和 Lambda Wrapper 生成的 SQL 相同
SELECT * FROM user WHERE id = (select MAX(id) from table)
groupBy
方法是 MyBatis-Plus 中用于构建查询条件的高级方法之一,它用于设置查询结果的分组条件。通过指定一个或多个字段,groupBy
方法可以生成 SQL 语句中的 GROUP BY 子句。
QueryWrapper
LambdaQueryWrapper
UpdateWrapper
LambdaUpdateWrapper
/**
* 分组:GROUP BY 字段, ...
* 例: groupBy(true, "id")
*
* @param condition 执行条件
* @param column 单个字段
* @return children
*/
Children groupBy(boolean condition, R column);
/**
* 分组:GROUP BY 字段, ...
* 例: groupBy("id")
*
* @param column 单个字段
* @return children
*/
default Children groupBy(R column) {
return groupBy(true, column);
}
/**
* 分组:GROUP BY 字段, ...
* 例: groupBy(true, Arrays.asList("id", "name"))
*
* @param condition 执行条件
* @param columns 字段数组
* @return children
*/
Children groupBy(boolean condition, List columns);
/**
* 分组:GROUP BY 字段, ...
* 例: groupBy(Arrays.asList("id", "name"))
*
* @param columns 字段数组
* @return children
*/
default Children groupBy(List columns) {
return groupBy(true, columns);
}
/**
* 分组:GROUP BY 字段, ...
* 例: groupBy("id", "name")
*
* @param column 单个字段
* @param columns 字段数组
* @return children
*/
default Children groupBy(R column, R... columns) {
return groupBy(true, column, columns);
}
/**
* 分组:GROUP BY 字段, ...
* 例: groupBy(true, "id", "name")
*
* @param condition 执行条件
* @param column 单个字段
* @param columns 字段数组
* @return children
*/
Children groupBy(boolean condition, R column, R... columns);
/**
* 分组:GROUP BY 字段, ...
* 例: groupBy(true, "id", Arrays.asList("name"))
*
* @param condition 执行条件
* @param column 单个字段
* @param columns 字段数组
* @return children
* @since 3.5.4
*/
Children groupBy(boolean condition, R column, List columns);
orderByAsc
方法是 MyBatis-Plus 中用于构建查询条件的高级方法之一,它用于设置查询结果的升序排序条件。通过指定一个或多个字段,orderByAsc
方法可以生成 SQL 语句中的 ORDER BY 子句,并指定升序排序。
QueryWrapper
LambdaQueryWrapper
UpdateWrapper
LambdaUpdateWrapper
/**
* 排序:ORDER BY 字段, ... ASC
* 例: orderByAsc(true, "id")
*
* @param condition 执行条件
* @param column 单个字段
* @return children
*/
default Children orderByAsc(boolean condition, R column) {
return orderBy(condition, true, column);
}
/**
* 排序:ORDER BY 字段, ... ASC
* 例: orderByAsc("id")
*
* @param column 单个字段
* @return children
*/
default Children orderByAsc(R column) {
return orderByAsc(true, column);
}
/**
* 排序:ORDER BY 字段, ... ASC
* 例: orderByAsc(true, Arrays.asList("id", "name"))
*
* @param condition 执行条件
* @param columns 字段数组
* @return children
*/
default Children orderByAsc(boolean condition, List columns) {
return orderBy(condition, true, columns);
}
/**
* 排序:ORDER BY 字段, ... ASC
* 例: orderByAsc(Arrays.asList("id", "name"))
*
* @param columns 字段数组
* @return children
*/
default Children orderByAsc(List columns) {
return orderByAsc(true, columns);
}
/**
* 排序:ORDER BY 字段, ... ASC
*
* @param column 字段
* @param columns 字段数组
* @return children
*/
default Children orderByAsc(R column, R... columns) {
return orderByAsc(true, column, columns);
}
/**
* 排序:ORDER BY 字段, ... ASC
*
* @param condition 执行条件
* @param column 字段
* @param columns 字段数组
*/
default Children orderByAsc(boolean condition, R column, R... columns) {
return orderBy(condition, true, column, columns);
}
/**
* 排序:ORDER BY 字段, ... ASC
* 例: orderByAsc(true, Arrays.asList("id", "name"))
*
* @param condition 执行条件
* @param columns 字段数组
* @return children
* @since 3.5.4
*/
default Children orderByAsc(boolean condition, R column, List columns) {
return orderBy(condition, true, column, columns);
}
orderByDesc
方法是 MyBatis-Plus 中用于构建查询条件的高级方法之一,它用于设置查询结果的降序排序条件。通过指定一个或多个字段,orderByDesc
方法可以生成 SQL 语句中的 ORDER BY 子句,并指定降序排序。
QueryWrapper
LambdaQueryWrapper
UpdateWrapper
LambdaUpdateWrapper
/**
* 排序:ORDER BY 字段, ... DESC
* 例: orderByDesc(true, "id")
*
* @param condition 执行条件
* @param column 字段
* @return children
*/
default Children orderByDesc(boolean condition, R column) {
return orderBy(condition, false, column);
}
/**
* 排序:ORDER BY 字段, ... DESC
* 例: orderByDesc("id")
*
* @param column 字段
* @return children
*/
default Children orderByDesc(R column) {
return orderByDesc(true, column);
}
/**
* 排序:ORDER BY 字段, ... DESC
* 例: orderByDesc(true, Arrays.asList("id", "name"))
*
* @param condition 执行条件
* @param columns 字段列表
* @return children
*/
default Children orderByDesc(boolean condition, List columns) {
return orderBy(condition, false, columns);
}
/**
* 排序:ORDER BY 字段, ... DESC
*
* @param columns 字段列表
*/
default Children orderByDesc(List columns) {
return orderByDesc(true, columns);
}
/**
* 排序:ORDER BY 字段, ... DESC
*
* @param column 单个字段
* @param columns 字段列表
*/
default Children orderByDesc(R column, R... columns) {
return orderByDesc(true, column, columns);
}
/**
* 排序:ORDER BY 字段, ... DESC
*
* @param condition 执行条件
* @param column 单个字段
* @param columns 字段列表
*/
default Children orderByDesc(boolean condition, R column, R... columns) {
return orderBy(condition, false, column, CollectionUtils.toList(columns));
}
/**
* 排序:ORDER BY 字段, ... DESC
*
* @param condition 执行条件
* @param column 单个字段
* @param columns 字段列表
* @since 3.5.4
*/
default Children orderByDesc(boolean condition, R column, List columns) {
return orderBy(condition, false, column, columns);
}
orderBy
方法是 MyBatis-Plus 中用于构建查询条件的高级方法之一,它用于设置查询结果的排序条件。通过指定一个或多个字段以及排序方向(升序或降序),orderBy
方法可以生成 SQL 语句中的 ORDER BY 子句。
QueryWrapper
LambdaQueryWrapper
UpdateWrapper
LambdaUpdateWrapper
/**
* 排序:ORDER BY 字段, ...
* 例: orderBy(true, "id")
*
* @param condition 执行条件
* @param isAsc 是否是 ASC 排序
* @param column 单个字段
* @return children
*/
Children orderBy(boolean condition, boolean isAsc, R column);
/**
* 排序:ORDER BY 字段, ...
* 例: orderBy(true, Arrays.asList("id", "name"))
*
* @param condition 执行条件
* @param isAsc 是否是 ASC 排序
* @param columns 字段列表
* @return children
*/
Children orderBy(boolean condition, boolean isAsc, List columns);
/**
* 排序:ORDER BY 字段, ...
*
* @param condition 执行条件
* @param isAsc 是否是 ASC 排序
* @param columns 字段列表
* @return children
*/
Children orderBy(boolean condition, boolean isAsc, R column, R... columns);
/**
* 排序:ORDER BY 字段, ...
*
* @param condition 执行条件
* @param isAsc 是否是 ASC 排序
* @param columns 字段列表
* @return children
* @since 3.5.4
*/
Children orderBy(boolean condition, boolean isAsc, R column, List columns);
普通 Wrapper (QueryWrapper):
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.orderBy(true, true, "id", "name");
Lambda Wrapper (LambdaQueryWrapper):
LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.orderBy(true, true, User::getId, User::getName);
生成的 SQL
-- 普通 Wrapper 和 Lambda Wrapper 生成的 SQL 相同
SELECT * FROM user ORDER BY id ASC, name ASC
排序可以应用于查询结果的展示,也可以用于优化查询性能,例如通过排序来减少需要扫描的数据量。
having
方法是 MyBatis-Plus 中用于构建查询条件的高级方法之一,它用于设置 HAVING 子句,通常与 GROUP BY 一起使用,用于对分组后的数据进行条件筛选。
QueryWrapper
LambdaQueryWrapper
UpdateWrapper
LambdaUpdateWrapper
/**
* HAVING ( sql语句 )
* 例1: having("sum(age) > 10")
* 例2: having("sum(age) > {0}", 10)
*
* @param sqlHaving sql 语句
* @param params 参数数组
* @return children
*/
default Children having(String sqlHaving, Object... params) {
return having(true, sqlHaving, params);
}
/**
* HAVING ( sql语句 )
* 例1: having(true, "sum(age) > 10")
* 例2: having(true, "sum(age) > {0}", 10)
*
* @param condition 执行条件
* @param sqlHaving sql 语句
* @param params 参数数组
* @return children
*/
Children having(boolean condition, String sqlHaving, Object... params);
普通 Wrapper (QueryWrapper):
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.groupBy("age").having("sum(age) > 10");
Lambda Wrapper (LambdaQueryWrapper):
LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.groupBy(User::getAge).having("sum(age) > {0}", 10);
生成的 SQL
-- 普通 Wrapper 和 Lambda Wrapper 生成的 SQL 相同
SELECT * FROM user GROUP BY age HAVING sum(age) > 10
having
方法通常与groupBy
方法一起使用,用于对分组后的数据进行进一步的筛选。- 在使用
having
方法时,确保sqlHaving
参数是一个有效的 SQL 语句,它将直接嵌入到生成的 SQL 中,因此需要确保其安全性和正确性,应避免 SQL 由前端动态参数传入并直接引用。params
参数用于替换sqlHaving
中的占位符,确保提供的参数类型和数量与占位符匹配。
func
方法是 MyBatis-Plus 中用于构建查询条件的高级方法之一,它提供了一种在链式调用中根据条件执行不同查询操作的机制。通过传入一个 Consumer
函数式接口,func
方法允许你在不中断链式调用的情况下,根据条件执行不同的查询构建逻辑。
QueryWrapper
LambdaQueryWrapper
UpdateWrapper
LambdaUpdateWrapper
/**
* 消费函数
*
* @param consumer 消费函数
* @return children
*/
default Children func(Consumer consumer) {
return func(true, consumer);
}
/**
* 消费函数
*
* @param condition 执行条件
* @param consumer 消费函数
* @return children
* @since 3.3.1
*/
Children func(boolean condition, Consumer consumer);
普通 Wrapper (QueryWrapper
):
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.func(i -> {
if (true) {
i.eq("id", 1);
} else {
i.ne("id", 1);
}
});
Lambda Wrapper (LambdaQueryWrapper):
LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.func(i -> {
if (true) {
i.eq(User::getId, 1);
} else {
i.ne(User::getId, 1);
}
});
生成的 SQL
-- 根据条件生成的 SQL 会有所不同
-- 如果条件为 true,则生成的 SQL 为:
SELECT * FROM user WHERE id = 1
-- 如果条件为 false,则生成的 SQL 为:
SELECT * FROM user WHERE id != 1
注意事项
func
方法提供了一种灵活的方式来根据条件动态构建查询条件,而不需要中断链式调用。func
方法时,确保 Consumer
函数式接口中的逻辑正确构建了所需的查询条件。condition
参数用于控制是否应用 Consumer
逻辑,这允许你根据某些条件动态添加查询条件。func
方法允许执行复杂的逻辑,因此在使用时需要特别注意代码的可读性和维护性。or
方法是 MyBatis-Plus 中用于构建查询条件的基本方法之一,它用于在查询条件中添加 OR 逻辑。通过调用 or
方法,可以改变后续查询条件的连接方式,从默认的 AND 连接变为 OR 连接。
QueryWrapper
LambdaQueryWrapper
UpdateWrapper
LambdaUpdateWrapper
/**
* 拼接 OR
*
* @return children
*/
default Children or() {
return or(true);
}
/**
* 拼接 OR
*
* @param condition 执行条件
* @return children
*/
Children or(boolean condition);
普通 Wrapper (QueryWrapper):
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.eq("id", 1).or().eq("name", "老王");
Lambda Wrapper (LambdaQueryWrapper):
LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(User::getId, 1).or().eq(User::getName, "老王");
生成的 SQL
-- 普通 Wrapper 和 Lambda Wrapper 生成的 SQL 相同
SELECT * FROM user WHERE id = 1 OR name = '老王'
OR 嵌套示例:
// 普通 Wrapper
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.or(i -> i.and(j -> j.eq("name", "李白").eq("status", "alive"))
.or(j -> j.eq("name", "杜甫").eq("status", "alive")));
// Lambda Wrapper
LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.or(i -> i.and(j -> j.eq(User::getName, "李白").eq(User::getStatus, "alive"))
.or(j -> j.eq(User::getName, "杜甫").eq(User::getStatus, "alive")));
生成的 SQL
-- 普通 Wrapper 和 Lambda Wrapper 生成的 SQL 相同
SELECT * FROM user WHERE (name = '李白' AND status = 'alive') OR (name = '杜甫' AND status = 'alive')
- 主动调用
or
方法表示紧接着下一个查询条件方法不是用and
连接,而是用or
连接。- 如果不调用
or
方法,则默认使用and
连接查询条件。or
方法可以嵌套使用,通过传入Consumer
函数式接口来构建复杂的 OR 嵌套条件。- 在使用
or
方法时,确保condition
参数正确控制了 OR 逻辑的应用。or
方法的嵌套使用可以构建复杂的查询逻辑,但需要注意代码的可读性和维护性。
and
方法是 MyBatis-Plus 中用于构建查询条件的基本方法之一,它用于在查询条件中添加 AND 逻辑。通过调用 and
方法,可以创建 AND 嵌套条件,即在一个 AND 逻辑块中包含多个查询条件。
QueryWrapper
LambdaQueryWrapper
UpdateWrapper
LambdaUpdateWrapper
/**
* AND 嵌套
*
* 例: and(i -> i.eq("name", "李白").ne("status", "活着"))
*
*
* @param consumer 消费函数
* @return children
*/
default Children and(Consumer consumer) {
return and(true, consumer);
}
/**
* AND 嵌套
*
* 例: and(i -> i.eq("name", "李白").ne("status", "活着"))
*
*
* @param condition 执行条件
* @param consumer 消费函数
* @return children
*/
Children and(boolean condition, Consumer consumer);
普通 Wrapper (QueryWrapper):
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.and(i -> i.and(j -> j.eq("name", "李白").eq("status", "alive"))
.and(j -> j.eq("name", "杜甫").eq("status", "alive")));
Lambda Wrapper (LambdaQueryWrapper):
LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.and(i -> i.and(j -> j.eq(User::getName, "李白").eq(User::getStatus, "alive"))
.and(j -> j.eq(User::getName, "杜甫").eq(User::getStatus, "alive")));
生成的 SQL
-- 普通 Wrapper 和 Lambda Wrapper 生成的 SQL 相同
SELECT * FROM user WHERE ((name = '李白' AND status = 'alive') AND (name = '杜甫' AND status = 'alive'))
nested
方法是 MyBatis-Plus 中用于构建查询条件的高级方法之一,它用于创建一个独立的查询条件块,不带默认的 AND 或 OR 逻辑。通过调用 nested
方法,可以在查询条件中添加一个嵌套的子句,该子句可以包含多个查询条件,并且可以被外部查询条件通过 AND 或 OR 连接。
QueryWrapper
LambdaQueryWrapper
UpdateWrapper
LambdaUpdateWrapper
/**
* 正常嵌套 不带 AND 或者 OR
*
* 例: nested(i -> i.eq("name", "李白").ne("status", "活着"))
*
*
* @param consumer 消费函数
* @return children
*/
default Children nested(Consumer consumer) {
return nested(true, consumer);
}
/**
* 正常嵌套 不带 AND 或者 OR
*
* 例: nested(i -> i.eq("name", "李白").ne("status", "活着"))
*
*
* @param condition 执行条件
* @param consumer 消费函数
* @return children
*/
Children nested(boolean condition, Consumer consumer);
普通 Wrapper (QueryWrapper):
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.nested(i -> i.eq("name", "李白").ne("status", "活着"));
Lambda Wrapper (LambdaQueryWrapper):
LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.nested(i -> i.eq(User::getName, "李白").ne(User::getStatus, "活着"));
生成的 SQL
-- 普通 Wrapper 和 Lambda Wrapper 生成的 SQL 相同
SELECT * FROM user WHERE (name = '李白' AND status <> '活着')
nested
方法创建的查询条件块是一个独立的子句,可以被外部查询条件通过 AND 或 OR 连接。- 在使用
nested
方法时,确保Consumer
函数式接口中的逻辑正确构建了所需的查询条件。
apply
方法是 MyBatis-Plus 中用于构建查询条件的高级方法之一,它允许你直接拼接 SQL 片段到查询条件中。这个方法特别适用于需要使用数据库函数或其他复杂 SQL 构造的场景。
QueryWrapper
LambdaQueryWrapper
UpdateWrapper
LambdaUpdateWrapper
/**
* 拼接 sql
* !! 会有 sql 注入风险 !!
* 例1: apply("id = 1")
* 例2: apply("date_format(dateColumn,'%Y-%m-%d') = '2008-08-08'")
* 例3: apply("date_format(dateColumn,'%Y-%m-%d') = {0}", LocalDate.now())
* 例4: apply("type={0,javaType=int,jdbcType=NUMERIC,typeHandler=xxx.xxx.MyTypeHandler}", "待处理字符串")
*
* @param values 数据数组
* @return children
*/
default Children apply(String applySql, Object... values) {
return apply(true, applySql, values);
}
/**
* 拼接 sql
* !! 会有 sql 注入风险 !!
* 例1: apply("id = 1")
* 例2: apply("date_format(dateColumn,'%Y-%m-%d') = '2008-08-08'")
* 例3: apply("date_format(dateColumn,'%Y-%m-%d') = {0}", LocalDate.now())
* 例4: apply("type={0,javaType=int,jdbcType=NUMERIC,typeHandler=xxx.xxx.MyTypeHandler}", "待处理字符串")
*
* @param condition 执行条件
* @param values 数据数组
* @return children
*/
Children apply(boolean condition, String applySql, Object... values);
普通 Wrapper (QueryWrapper):
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.apply("id = 1");
Lambda Wrapper (LambdaQueryWrapper):
LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.apply("date_format(dateColumn, '%Y-%m-%d') = '2008-08-08'");
使用参数占位符的示例:
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.apply("date_format(dateColumn, '%Y-%m-%d') = {0}", "2008-08-08");
生成的 SQL
-- 普通 Wrapper 生成的 SQL
SELECT * FROM user WHERE id = 1
-- Lambda Wrapper 生成的 SQL
SELECT * FROM user WHERE date_format(dateColumn, '%Y-%m-%d') = '2008-08-08'
-- 使用参数占位符生成的 SQL
SELECT * FROM user WHERE date_format(dateColumn, '%Y-%m-%d') = '2008-08-08'
apply
方法可用于拼接包含数据库函数的 SQL 片段。- 动态入参的
params
对应applySql
内部的{index}
部分,这样是不会有 SQL 注入风险的。如果直接将参数拼接到 SQL 中,则会有 SQL 注入风险,故应避免 SQL 由前端动态参数传入并直接引用。
last
方法是 MyBatis-Plus 中用于构建查询条件的高级方法之一,它允许你直接在查询的最后添加一个 SQL 片段,而不受 MyBatis-Plus 的查询优化规则影响。这个方法应该谨慎使用,因为它可能会绕过 MyBatis-Plus 的查询优化。
QueryWrapper
LambdaQueryWrapper
UpdateWrapper
LambdaUpdateWrapper
/**
* 无视优化规则直接拼接到 sql 的最后(有sql注入的风险,请谨慎使用)
* 例: last("limit 1")
* 注意只能调用一次,多次调用以最后一次为准
*
* @param lastSql sql语句
* @return children
*/
default Children last(String lastSql) {
return last(true, lastSql);
}
/**
* 无视优化规则直接拼接到 sql 的最后(有sql注入的风险,请谨慎使用)
* 例: last("limit 1")
* 注意只能调用一次,多次调用以最后一次为准
*
* @param condition 执行条件
* @param lastSql sql语句
* @return children
*/
Children last(boolean condition, String lastSql);
普通 Wrapper (QueryWrapper):
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.last("limit 1");
Lambda Wrapper (LambdaQueryWrapper):
LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.last("limit 1");
生成的 SQL
-- 普通 Wrapper 和 Lambda Wrapper 生成的 SQL 相同
SELECT * FROM user LIMIT 1
last
方法只能调用一次,多次调用将以最后一次为准。- 使用
last
方法会绕过 MyBatis-Plus 的查询优化规则,可能会导致查询效率降低。- 因为
lastSql
参数直接拼接到 SQL 中,所以必须确保输入的 SQL 片段是安全的,即保障lastSql
应该是后端自行控制,而不是动态参数由前端传入。
exists
代表存在量词,比如
select name from student where exists (select * from student_num AS sb where sn=student.num and sn='111');
子查询:select * from student_num AS sb where sn=student.num and sn='111'
子查询不会返回任何数据,只产生逻辑真值true(存在)/false(不存在),判断是否有个数据是111的数据 ,存在才会继续查询,不存在外层查询无效,就不会进行查询操作。
exists
方法是 MyBatis-Plus 中用于构建查询条件的高级方法之一,它用于在查询中添加一个 EXISTS 子查询。通过调用 exists
方法,可以将一个完整的 SQL 子查询作为 EXISTS 条件添加到主查询中。
QueryWrapper
LambdaQueryWrapper
UpdateWrapper
LambdaUpdateWrapper
/**
* 拼接 EXISTS ( sql语句 )
* !! sql 注入方法 !!
* 例: exists("select id from table where age = 1")
*
* @param existsSql sql语句
* @param values 数据数组
* @return children
*/
default Children exists(String existsSql, Object... values) {
return exists(true, existsSql, values);
}
/**
* 拼接 EXISTS ( sql语句 )
* !! sql 注入方法 !!
* 例: exists("select id from table where age = 1")
*
* @param condition 执行条件
* @param existsSql sql语句
* @param values 数据数组
* @return children
*/
Children exists(boolean condition, String existsSql, Object... values);
普通 Wrapper (QueryWrapper):
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.exists("select id from table where age = 1");
Lambda Wrapper (LambdaQueryWrapper):
LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.exists("select id from table where age = 1");
生成的 SQL
-- 普通 Wrapper 和 Lambda Wrapper 生成的 SQL 相同
SELECT * FROM user WHERE EXISTS (select id from table where age = 1)
exists
方法用于添加一个 EXISTS 子查询,这通常用于检查子查询是否返回任何行。- 在使用
exists
方法时,确保existsSql
参数是一个有效的 SQL 子查询,它将直接嵌入到生成的 SQL 中,因此需要确保其安全性和正确性,应避免 SQL 由前端动态参数传入并直接引用。
notExists
方法是 MyBatis-Plus 中用于构建查询条件的高级方法之一,它用于在查询中添加一个 NOT EXISTS 子查询。通过调用 notExists
方法,可以将一个完整的 SQL 子查询作为 NOT EXISTS 条件添加到主查询中。
QueryWrapper
LambdaQueryWrapper
UpdateWrapper
LambdaUpdateWrapper
/**
* 拼接 NOT EXISTS ( sql语句 )
* !! sql 注入方法 !!
* 例: notExists("select id from table where age = 1")
*
* @param existsSql sql语句
* @param values 数据数组
* @return children
*/
default Children notExists(String existsSql, Object... values) {
return notExists(true, existsSql, values);
}
/**
* 拼接 NOT EXISTS ( sql语句 )
* !! sql 注入方法 !!
* 例: notExists("select id from table where age = 1")
*
* @param condition 执行条件
* @param existsSql sql语句
* @param values 数据数组
* @return children
*/
Children notExists(boolean condition, String existsSql, Object... values);
普通 Wrapper (QueryWrapper):
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.notExists("select id from table where age = 1");
Lambda Wrapper (LambdaQueryWrapper):
LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.notExists("select id from table where age = 1");
生成的 SQL
-- 普通 Wrapper 和 Lambda Wrapper 生成的 SQL 相同
SELECT * FROM user WHERE NOT EXISTS (select id from table where age = 1)
select
方法是 MyBatis-Plus 中用于构建查询条件的高级方法之一,它用于设置查询的字段。通过调用 select
方法,可以指定在查询结果中包含哪些字段,从而实现字段级别的查询定制。
QueryWrapper
LambdaQueryWrapper
/**
* 指定查询字段
*
* @param columns 字段列表
* @return children
*/
@SuppressWarnings("unchecked")
default Children select(R... columns) {
return select(true, columns);
}
/**
* 指定查询字段
*
* @param condition 执行条件
* @param columns 字段列表
* @return children
*/
@SuppressWarnings("unchecked")
default Children select(boolean condition, R... columns) {
return select(condition, Arrays.asList(columns));
}
/**
* 指定查询字段
*
* @param columns 字段列表
* @return children
*/
default Children select(List columns) {
return select(true, columns);
}
/**
* 指定查询字段
*
* @param condition 执行条件
* @param columns 字段列表
* @return children
*/
Children select(boolean condition, List columns);
/**
* 过滤查询的字段信息(主键除外!)
* 注意只有内部有 entity 才能使用该方法
*/
default Children select(Predicate predicate) {
return select(null, predicate);
}
/**
* 过滤查询的字段信息(主键除外!)
* 例1: 只要 java 字段名以 "test" 开头的 -> select(i -> i.getProperty().startsWith("test"))
* 例2: 只要 java 字段属性是 CharSequence 类型的 -> select(TableFieldInfo::isCharSequence)
* 例3: 只要 java 字段没有填充策略的 -> select(i -> i.getFieldFill() == FieldFill.DEFAULT)
* 例4: 要全部字段 -> select(i -> true)
* 例5: 只要主键字段 -> select(i -> false)
*
* @param predicate 过滤方式
* @return children
*/
Children select(Class entityClass, Predicate predicate);
普通 Wrapper (QueryWrapper):
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.select("id", "name", "age");
Lambda Wrapper (LambdaQueryWrapper):
LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.select(User::getId, User::getName, User::getAge);
使用 Predicate 过滤字段的示例:
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.select(i -> i.getProperty().startsWith("test"));
生成的 SQL
-- 普通 Wrapper 和 Lambda Wrapper 生成的 SQL 相同
SELECT id, name, age FROM user
-- 使用 Predicate 过滤字段生成的 SQL
SELECT testField1, testField2 FROM user
select
方法分为两类:第一类直接指定要查询的字段名,第二类通过Predicate
过滤字段。- 第二类方法用于过滤查询字段(主键除外),如果入参不包含
entityClass
,则在调用前需要确保wrapper
内的entity
属性有值。- 这两类方法重复调用时,以最后一次调用为准。
- 在使用
select
方法时,确保指定的字段名或过滤条件正确,以避免查询结果不符合预期。
set
方法是 MyBatis-Plus 中用于构建更新操作的高级方法之一,它用于设置更新语句中的 SET 字段。通过调用 set
方法,可以指定在更新操作中要修改的字段及其新值。
UpdateWrapper
LambdaUpdateWrapper
/**
* 设置 更新 SQL 的 SET 片段
*
* @param column 字段
* @param val 值
* @return children
*/
default Children set(R column, Object val) {
return set(true, column, val);
}
/**
* 设置 更新 SQL 的 SET 片段
*
* @param condition 是否加入 set
* @param column 字段
* @param val 值
* @return children
*/
default Children set(boolean condition, R column, Object val) {
return set(condition, column, val, null);
}
/**
* 设置 更新 SQL 的 SET 片段
*
* @param column 字段
* @param val 值
* @param mapping 例: javaType=int,jdbcType=NUMERIC,typeHandler=xxx.xxx.MyTypeHandler
* @return children
*/
default Children set(R column, Object val, String mapping) {
return set(true, column, val, mapping);
}
/**
* 设置 更新 SQL 的 SET 片段
*
* @param condition 是否加入 set
* @param column 字段
* @param val 值
* @param mapping 例: javaType=int,jdbcType=NUMERIC,typeHandler=xxx.xxx.MyTypeHandler
* @return children
*/
Children set(boolean condition, R column, Object val, String mapping);
普通 Wrapper (UpdateWrapper):
UpdateWrapper updateWrapper = new UpdateWrapper<>();
updateWrapper.set("name", "老李头");
Lambda Wrapper (LambdaUpdateWrapper):
LambdaUpdateWrapper lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
lambdaUpdateWrapper.set(User::getName, "老李头");
生成的 SQL
-- 普通 Wrapper 和 Lambda Wrapper 生成的 SQL 相同
UPDATE user SET name = '老李头'
使用条件控制的示例:
UpdateWrapper updateWrapper = new UpdateWrapper<>();
updateWrapper.set(true, "name", "");
生成的 SQL
-- 使用条件控制的 SQL
UPDATE user SET name = ''
set
方法用于设置更新语句中的 SET 字段,可以指定要更新的字段及其新值。- 当
val
参数为空字符串时,数据库字段值将变为空字符串。- 当
val
参数为null
时,数据库字段值将变为null
。
setSql
方法是 MyBatis-Plus 中用于构建更新操作的高级方法之一,它允许你直接设置更新语句中的 SET 部分 SQL。通过调用 setSql
方法,可以将一个自定义的 SQL 片段作为 SET 子句添加到更新语句中。
UpdateWrapper
LambdaUpdateWrapper
/**
* 设置 更新 SQL 的 SET 片段
*
* @param setSql set sql
* 例1: setSql("id=1")
* 例2: setSql("dateColumn={0}", LocalDate.now())
* 例4: setSql("type={0,javaType=int,jdbcType=NUMERIC,typeHandler=xxx.xxx.MyTypeHandler}", "待处理字符串")
* @return children
*/
default Children setSql(String setSql, Object... params) {
return setSql(true, setSql, params);
}
/**
* 设置 更新 SQL 的 SET 片段
*
* @param condition 执行条件
* @param setSql set sql
* 例1: setSql("id=1")
* 例2: setSql("dateColumn={0}", LocalDate.now())
* 例4: setSql("type={0,javaType=int,jdbcType=NUMERIC,typeHandler=xxx.xxx.MyTypeHandler}", "待处理字符串")
* @return children
*/
Children setSql(boolean condition, String setSql, Object... params);
setSql("name = '老李头'")
setSql("dateColumn={0}", LocalDate.now())
setSql("type={0,javaType=int,jdbcType=NUMERIC,typeHandler=xxx.xxx.MyTypeHandler}", "待处理字符串");
setSql
方法用于设置更新语句中的 SET 部分 SQL,这通常用于需要使用复杂 SQL 构造的场景。- 在使用
setSql
方法时,确保sql
参数是一个有效的 SQL 片段,它将直接嵌入到生成的 SQL 中,因此需要确保其安全性和正确性,应避免 SQL 由前端动态参数传入并直接引用
setIncrBy
方法是 MyBatis-Plus 中用于更新操作的高级方法之一,它允许你指定一个字段,并使其在数据库中的值增加指定的数值。这个方法特别适用于需要对数值字段进行增量操作的场景。
LambdaUpdateWrapper
/**
* 字段自增变量 val 值
*
* @param column 字段
* @param val 变量值 1 字段自增 + 1
*/
default Children setIncrBy(R column, Number val) {
return setIncrBy(true, column, val);
}
/**
* 字段自增变量 val 值
*
* @param condition 是否加入 set
* @param column 字段
* @param val 变量值 1 字段自增 + 1
*/
Children setIncrBy(boolean condition, R column, Number val);
普通 Wrapper (UpdateWrapper):
UpdateWrapper updateWrapper = new UpdateWrapper<>();
updateWrapper.setIncrBy(Product::getNum, 1);
Lambda Wrapper (LambdaUpdateWrapper):
LambdaUpdateWrapper lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
lambdaUpdateWrapper.setIncrBy(Product::getNum, 1);
生成的 SQL
-- 普通 Wrapper 和 Lambda Wrapper 生成的 SQL 相同
UPDATE product SET num = num + 1
setIncrBy
方法用于对指定字段进行自增操作,这通常用于需要对数值字段进行增量更新的场景。
setDecrBy
方法是 MyBatis-Plus 中用于更新操作的高级方法之一,它允许你指定一个字段,并使其在数据库中的值减少指定的数值。这个方法特别适用于需要对数值字段进行减量操作的场景。
LambdaUpdateWrapper
/**
* 字段自减变量 val 值
*
* @param column 字段
* @param val 变量值 1 字段自减 - 1
*/
default Children setDecrBy(R column, Number val) {
return setDecrBy(true, column, val);
}
/**
* 字段自减变量 val 值
*
* @param condition 是否加入 set
* @param column 字段
* @param val 变量值 1 字段自减 - 1
*/
Children setDecrBy(boolean condition, R column, Number val);
普通 Wrapper (UpdateWrapper):
UpdateWrapper updateWrapper = new UpdateWrapper<>();
updateWrapper.setDecrBy("num", 1);
Lambda Wrapper (LambdaUpdateWrapper):
LambdaUpdateWrapper lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
lambdaUpdateWrapper.setDecrBy(Product::getNum, 1);
生成的 SQL
-- 普通 Wrapper 和 Lambda Wrapper 生成的 SQL 相同
UPDATE product SET num = num - 1
lambda
方法是一个便捷的方法,它允许你从 QueryWrapper
或 UpdateWrapper
对象中获取对应的 LambdaQueryWrapper
或 LambdaUpdateWrapper
对象。这样,你就可以使用 Lambda 表达式来构建查询或更新条件,使得代码更加简洁和类型安全。
QueryWrapper
UpdateWrapper
/**
* 返回一个支持 lambda 函数写法的 wrapper
*/
public LambdaQueryWrapper lambda() {
return new LambdaQueryWrapper<>(getEntity(), getEntityClass(), sqlSelect, paramNameSeq, paramNameValuePairs,
expression, paramAlias, lastSql, sqlComment, sqlFirst);
}
从 QueryWrapper 获取 LambdaQueryWrapper:
QueryWrapper queryWrapper = new QueryWrapper<>();
LambdaQueryWrapper lambdaQueryWrapper = queryWrapper.lambda();
// 使用 Lambda 表达式构建查询条件
lambdaQueryWrapper.eq("name", "张三");
从 UpdateWrapper 获取 LambdaUpdateWrapper:
UpdateWrapper updateWrapper = new UpdateWrapper<>();
LambdaUpdateWrapper lambdaUpdateWrapper = updateWrapper.lambda();
// 使用 Lambda 表达式构建更新条件
lambdaUpdateWrapper.set(User::getName, "李四");
lambda
方法返回一个LambdaWrapper
对象,具体类型取决于调用它的Wrapper
类型。- 在
QueryWrapper
上调用lambda
方法将返回一个LambdaQueryWrapper
。- 在
UpdateWrapper
上调用lambda
方法将返回一个LambdaUpdateWrapper
。- 使用 Lambda 表达式可以避免直接使用字符串来指定字段名,从而减少错误并提高代码的可读性。
- 在使用
lambda
方法时,确保你已经正确地初始化了QueryWrapper
或UpdateWrapper
对象。- 一旦获取了
LambdaWrapper
对象,你就可以使用 Lambda 表达式来构建查询或更新条件,这将使得代码更加类型安全和易于维护。