跳到主要内容

条件构造器

条件构造器是 MyBatis Plus 最强大的功能之一,它提供了优雅的方式来构建复杂的查询条件。本章将详细介绍各种条件构造器的使用方法。

Wrapper 家族

MyBatis Plus 提供了多种 Wrapper 类型:

Wrapper 类说明
QueryWrapper查询条件封装
LambdaQueryWrapper使用 Lambda 表达式的查询条件封装
UpdateWrapper更新条件封装
LambdaUpdateWrapper使用 Lambda 表达式的更新条件封装
AbstractWrapper所有 Wrapper 的父类,提供通用方法

推荐使用 Lambda

使用 Lambda 表达式的优势:

  • 避免字段名硬编码
  • 支持重构
  • 编译期检查
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("name", "张三");

LambdaQueryWrapper<User> lambdaWrapper = new LambdaQueryWrapper<>();
lambdaWrapper.eq(User::getName, "张三");

比较操作

等于 eq

@Test
void testEq() {
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(User::getName, "张三");

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

@Test
void testEqWithCondition() {
String name = "张三";

LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(name != null, User::getName, name);

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

不等于 ne

@Test
void testNe() {
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.ne(User::getAge, 25);

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

大于 gt、大于等于 ge

@Test
void testGtGe() {
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.gt(User::getAge, 20)
.ge(User::getAge, 18);

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

小于 lt、小于等于 le

@Test
void testLtLe() {
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.lt(User::getAge, 30)
.le(User::getAge, 60);

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

BETWEEN between

@Test
void testBetween() {
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.between(User::getAge, 20, 30);

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

NOT BETWEEN notBetween

@Test
void testNotBetween() {
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.notBetween(User::getAge, 20, 30);

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

模糊查询

LIKE like

@Test
void testLike() {
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.like(User::getName, "张");

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

NOT LIKE notLike

@Test
void testNotLike() {
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.notLike(User::getName, "张");

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

LIKE LEFT likeLeft

@Test
void testLikeLeft() {
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.likeLeft(User::getName, "三");

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

LIKE RIGHT likeRight

@Test
void testLikeRight() {
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.likeRight(User::getName, "张");

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

范围查询

IN in

@Test
void testIn() {
List<Integer> ages = Arrays.asList(20, 25, 30);

LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.in(User::getAge, ages);

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

@Test
void testInArray() {
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.in(User::getAge, 20, 25, 30);

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

NOT IN notIn

@Test
void testNotIn() {
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.notIn(User::getAge, 20, 25, 30);

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

IS NULL isNull

@Test
void testIsNull() {
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.isNull(User::getEmail);

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

IS NOT NULL isNotNull

@Test
void testIsNotNull() {
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.isNotNull(User::getEmail);

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

分组与排序

GROUP BY groupBy

@Test
void testGroupBy() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.select("age", "COUNT(*) as count")
.groupBy("age");

List<Map<String, Object>> result = userMapper.selectMaps(wrapper);
result.forEach(System.out::println);
}

ORDER BY orderByAsc / orderByDesc

@Test
void testOrderBy() {
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.orderByAsc(User::getAge)
.orderByDesc(User::getCreateTime);

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

@Test
void testOrderByWithCondition() {
boolean isAsc = true;

LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.orderBy(true, isAsc, User::getAge);

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

HAVING having

@Test
void testHaving() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.select("age", "COUNT(*) as count")
.groupBy("age")
.having("COUNT(*) > {0}", 1);

List<Map<String, Object>> result = userMapper.selectMaps(wrapper);
}

逻辑连接

AND and

@Test
void testAnd() {
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(User::getName, "张三")
.and(w -> w.gt(User::getAge, 20).lt(User::getAge, 30));

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

生成的 SQL:

WHERE name = '张三' AND (age > 20 AND age < 30)

OR or

@Test
void testOr() {
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(User::getName, "张三")
.or()
.eq(User::getName, "李四");

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

@Test
void testOrNested() {
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(User::getName, "张三")
.or(w -> w.gt(User::getAge, 30).isNotNull(User::getEmail));

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

生成的 SQL:

WHERE name = '张三' OR (age > 30 AND email IS NOT NULL)

NESTED nested

@Test
void testNested() {
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.nested(w -> w.eq(User::getName, "张三").gt(User::getAge, 20));

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

生成的 SQL:

WHERE (name = '张三' AND age > 20)

其他条件

APPLY apply

用于拼接 SQL 片段:

@Test
void testApply() {
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.apply("date_format(create_time, '%Y-%m') = {0}", "2024-01");

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

@Test
void testApplyWithDate() {
String startDate = "2024-01-01";
String endDate = "2024-12-31";

LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.apply("create_time BETWEEN {0} AND {1}", startDate, endDate);

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

LAST last

在 SQL 末尾追加内容:

@Test
void testLast() {
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.last("LIMIT 10");

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

EXISTS exists

@Test
void testExists() {
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.exists("SELECT 1 FROM t_order WHERE t_order.user_id = t_user.id");

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

NOT EXISTS notExists

@Test
void testNotExists() {
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.notExists("SELECT 1 FROM t_order WHERE t_order.user_id = t_user.id");

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

UpdateWrapper

UpdateWrapper 用于构建更新条件。

基本更新

@Test
void testUpdateWrapper() {
LambdaUpdateWrapper<User> wrapper = new LambdaUpdateWrapper<>();
wrapper.eq(User::getName, "张三")
.set(User::getAge, 26)
.set(User::getEmail, "[email protected]");

int result = userMapper.update(null, wrapper);
}

更新为 NULL

@Test
void testUpdateToNull() {
LambdaUpdateWrapper<User> wrapper = new LambdaUpdateWrapper<>();
wrapper.eq(User::getId, 1L)
.set(User::getEmail, null);

int result = userMapper.update(null, wrapper);
}

setSql 自定义 SQL

@Test
void testSetSql() {
LambdaUpdateWrapper<User> wrapper = new LambdaUpdateWrapper<>();
wrapper.eq(User::getId, 1L)
.setSql("age = age + 1");

int result = userMapper.update(null, wrapper);
}

条件判断

条件参数

所有方法都支持条件判断:

@Test
void testCondition() {
String name = null;
Integer minAge = 20;
Integer maxAge = null;

LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(name != null, User::getName, name)
.ge(minAge != null, User::getAge, minAge)
.le(maxAge != null, User::getAge, maxAge);

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

动态条件构建

public List<User> searchUsers(String name, Integer minAge, Integer maxAge, String email) {
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();

wrapper.like(StringUtils.isNotBlank(name), User::getName, name)
.ge(minAge != null, User::getAge, minAge)
.le(maxAge != null, User::getAge, maxAge)
.like(StringUtils.isNotBlank(email), User::getEmail, email);

return userMapper.selectList(wrapper);
}

查询字段选择

select 指定字段

@Test
void testSelectFields() {
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.select(User::getId, User::getName, User::getAge)
.gt(User::getAge, 20);

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

排除字段

@Test
void testExcludeFields() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.select(User.class, info -> !info.getColumn().equals("password"));

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

实战示例

多条件组合查询

public IPage<User> searchUsers(UserQuery query, int pageNum, int pageSize) {
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();

wrapper.like(StringUtils.isNotBlank(query.getName()), User::getName, query.getName())
.eq(query.getAge() != null, User::getAge, query.getAge())
.between(query.getMinAge() != null && query.getMaxAge() != null,
User::getAge, query.getMinAge(), query.getMaxAge())
.like(StringUtils.isNotBlank(query.getEmail()), User::getEmail, query.getEmail())
.in(query.getStatusList() != null && !query.getStatusList().isEmpty(),
User::getStatus, query.getStatusList())
.orderByDesc(User::getCreateTime);

Page<User> page = new Page<>(pageNum, pageSize);
return userMapper.selectPage(page, wrapper);
}

复杂更新

public void updateUserStatus(Long userId, Integer newStatus, String operator) {
LambdaUpdateWrapper<User> wrapper = new LambdaUpdateWrapper<>();
wrapper.eq(User::getId, userId)
.set(User::getStatus, newStatus)
.set(User::getUpdateTime, LocalDateTime.now())
.set(User::getUpdateBy, operator)
.setSql("version = version + 1");

userMapper.update(null, wrapper);
}

统计查询

public Map<String, Object> getUserStatistics() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.select("COUNT(*) as total",
"AVG(age) as avgAge",
"MAX(age) as maxAge",
"MIN(age) as minAge",
"status");
wrapper.groupBy("status");

List<Map<String, Object>> stats = userMapper.selectMaps(wrapper);

Map<String, Object> result = new HashMap<>();
result.put("statistics", stats);
result.put("total", userMapper.selectCount(null));

return result;
}

小结

本章我们学习了:

  1. Wrapper 类型:QueryWrapper、LambdaQueryWrapper、UpdateWrapper、LambdaUpdateWrapper
  2. 比较操作:eq、ne、gt、ge、lt、le、between
  3. 模糊查询:like、likeLeft、likeRight、notLike
  4. 范围查询:in、notIn、isNull、isNotNull
  5. 分组排序:groupBy、orderByAsc、orderByDesc、having
  6. 逻辑连接:and、or、nested
  7. 高级用法:apply、last、exists、条件判断

参考资源