Mybatis plus链式调用

在日常使用 Mybatis Plus 进行数据访问层开发时,条件构造器 (QueryWrapper 和 LambdaQueryWrapper) 是我们构建动态 SQL 的得力助手。而链式调用(Chain Invocation)则是 Mybatis Plus 为这些构造器提供的一种极其优雅、可读性极高的编码风格,它能显著提升代码的简洁度和开发体验。

一、什么是链式调用

链式调用的核心思想在于:一个对象的方法在调用后,返回对象本身(通常是 this),使得后续的方法可以紧接着在前一个方法调用的结果上继续调用,形成一条连续的“链条”。

在 Mybatis Plus 的 QueryWrapper 和 LambdaQueryWrapper 中,绝大多数用于添加条件(如 eqlikegtorderBy 等)的方法都采用了这种设计。

二、传统方式 vs 链式调用

假设我们需要查询:状态为启用 (status=1)、姓名包含"张" (name like '%张%')、年龄大于 18 岁 (age > 18),并按照创建时间倒序排列 (create_time DESC) 的用户。

1. 传统方式 (非链式)

QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("status", 1);
queryWrapper.like("name", "张");
queryWrapper.gt("age", 18);
queryWrapper.orderByDesc("create_time");

List<User> userList = userMapper.selectList(queryWrapper);

这种方式清晰但略显冗余,每次调用都需要重复 queryWrapper 对象名。

2. 链式调用方式

QueryWrapper<User> queryWrapper = new QueryWrapper<User>()
    .eq("status", 1)
    .like("name", "张")
    .gt("age", 18)
    .orderByDesc("create_time");

List<User> userList = userMapper.selectList(queryWrapper);

代码行数减少 所有条件按照逻辑顺序依次排列,避免了重复书写对象变量名

三、LambdaQueryWrapper

LambdaQueryWrapper 在 QueryWrapper 的基础上,利用 Java 的 Lambda 表达式和方法引用,彻底消除了条件字段名硬编码字符串,带来了编译期的类型安全检查

LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<User>()
    .eq(User::getStatus, 1)          // 使用 User::getStatus 方法引用
    .like(User::getName, "张")       // 编译时检查字段名正确性
    .gt(User::getAge, 18)            // 避免字段名拼写错误
    .orderByDesc(User::getCreateTime); // 重构友好

List<User> userList = userMapper.selectList(lambdaQueryWrapper);

编译器会在你修改实体类属性名称时立即提示错误,避免运行时因字段名拼写错误导致的 SQL 异常, 也不会出现数据库表没有该字段的问题了

四、链式调用的常见方法

方法名作用示例注意事项
比较操作
eq等于 (=).eq(User::getName, "Alice")最常用条件,字段值精确匹配
ne不等于 (<>).ne(User::getStatus, 0)排除特定值
gt大于 (>).gt(User::getAge, 18)常用于数值/日期比较
ge大于等于 (>=).ge(User::getScore, 60)包含边界值
lt小于 (<).lt(User::getCreateTime, LocalDate.now())常用于范围查询
le小于等于 (<=).le(User::getPrice, 100.0)包含边界值
between在范围内 (BETWEEN).between(User::getAge, 20, 30)包含两端值(闭区间)
notBetween不在范围内 (NOT BETWEEN).notBetween(User::getId, 100, 200)排除指定区间
模糊查询
like模糊匹配 (%value%).like(User::getName, "张") → name LIKE '%张%'全模糊搜索,性能敏感时慎用
notLike模糊不匹配.notLike(User::getTitle, "test")排除包含特定字符串的记录
likeLeft左模糊 (%value).likeLeft(User::getCode, "001") → code LIKE '%001'常用于后缀匹配
likeRight右模糊 (value%).likeRight(User::getPhone, "138") → phone LIKE '138%'常用于前缀匹配
空值判断
isNull为 NULL.isNull(User::getDescription)等价 SQL: column IS NULL
isNotNull不为 NULL.isNotNull(User::getAvatar)等价 SQL: column IS NOT NULL
包含/不包含
in包含在集合中.in(User::getRoleId, Arrays.asList(1, 2, 3))集合参数避免空集合(会报错)
notIn不包含在集合中.notIn(User::getDeptId, deptIdList)常用于排除特定分类
分组
groupBy分组聚合.groupBy(User::getDeptId)
.groupBy(User::getGender, User::getAge)
可多字段分组,需配合select()使用聚合函数
排序
orderByAsc升序排序.orderByAsc(User::getCreateTime)
.orderByAsc(User::getAge, User::getId)
多字段排序时按参数顺序应用
orderByDesc降序排序.orderByDesc(User::getSalary)常用在时间戳、数值字段
orderBy自定义排序(可混用升降序).orderBy(true, true, User::getScore)
→ ORDER BY score ASC
参数:(boolean isAsc, boolean isAsc2, SFunction<?,?>... columns)
逻辑操作
andAND 连接后续条件.eq(...).and(w -> w.gt(...).or().lt(...))默认所有条件都是AND关系,显式and()用于嵌套复杂逻辑
orOR 连接后续条件.eq(...).or().like(...)
→ (a = b) OR (c LIKE d)
会改变整个条件链关系,慎用
选择字段
select指定返回字段.select(User::getId, User::getName)大幅提升性能,避免返回SELECT *
嵌套条件
nested嵌套条件组.nested(w -> w.eq(...).or(...))解决复杂逻辑:(A AND B) OR (C AND D)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值