Mybatis-plus 中 like or and eq 的混合查询使用

本文通过实例展示了在Mybatis-plus中如何使用like、or、and、eq进行复杂的混合查询,并指出在参数验证不当时可能出现的问题。在查询学生信息时,需求是查找name包含'a'、class_level包含'22'或ages等于22的记录。在实际代码实现中,由于eq方法会先转换参数再判断条件,当ageStr不是数字时会导致错误。因此,需要在调用eq之前先校验ageStr是否为有效数字,避免出现异常。修复后的代码确保了查询的正确性和健壮性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Mybatis-plus 中 like()、 or()、 and()、 eq() 的混合查询使用【下面为项目中的代码片段】

一、测试的表结构与数据如下
在这里插入图片描述
二、需要与查询的原始sql如下:
需求:查询name中带 “a” 或者 class_level 中带 “22” 或者 ages 等于 22的名单!

SELECT * FROM student WHERE name LIKE '%a%' AND ( class_level LIKE '%22%' OR ages = 22);

查询结果
在这里插入图片描述
三、mybatis-plus的查询代码:

String name = "a";
String level = "22";
String ageStr = "22";
LambdaQueryWrapper<Student> query = new LambdaQueryWrapper<>();
query.like(StringUtils.isNotEmpty(name), Student::getName, name)
        .and(wrapper -> wrapper.like(StringUtils.isNotEmpty(level), Student::getClassLevel, level ).or().eq(ageStr.matches("^[1-9]\\d*$"), Student::getAges, Integer.parseInt(ageStr)));
List<Student> studentList = studentService.list(query);

四、在实际工作中可能出现的问题,如果参数 ageStr并不是真正的数字时上面的写法是有问题的
因为 eq()函数会先执行 Integer.parseInt(ageStr) 然后再执行判断条件 ageStr.matches("1\d*$")是否是正数;所以需要调整如下:

String name = "a";
String level = "22";
String ageStr = "s22";
LambdaQueryWrapper<Student> query = new LambdaQueryWrapper<>();
query.like(StringUtils.isNotEmpty(name), Student::getName, name);
if (ageStr.matches("^[1-9]\\d*$")) {  //判断 ageStr是否是正数
    query.and(wrapper -> wrapper.like(StringUtils.isNotEmpty(level), Student::getClassLevel, level ).or().eq(Student::getAges, Integer.parseInt(ageStr)));
} else {
    query.and(wrapper -> wrapper.like(StringUtils.isNotEmpty(level), Student::getClassLevel, level ));
}
List<Student> studentList = studentService.list(query);

  1. 1-9 ↩︎

### 3.1 基于 QueryWrapper 的 ANDOR 组合查询MyBatis-Plus 中,使用 `QueryWrapper` 可以实现复杂的 ANDOR 条件组合查询。通过 `.eq()`、`.gt()`、`.like()` 等方法设置查询条件,并结合 `.and()` 和 `.or()` 方法进行逻辑连接。 例如,若需查询状态为“启用”(status = 1)且年龄等于 30 或姓名包含 “John” 的用户记录: ```java QueryWrapper<User> queryWrapper = new QueryWrapper<>(); queryWrapper.eq("status", 1) .and(wq -> wq.eq("age", 30).or().like("name", "John")); List<User> users = userMapper.selectList(queryWrapper); ``` 生成的 SQL 如下: ```sql SELECT * FROM user WHERE status = 1 AND (age = 30 OR name LIKE '%John%') ``` 该语句将返回所有状态为“启用”并且满足年龄等于 30 或者姓名中包含 “John” 的用户记录[^3]。 ### 3.2 使用 LambdaQueryWrapper 实现类型安全的 AND/OR 查询 相比 `QueryWrapper`,`LambdaQueryWrapper` 提供了更安全的类型检查机制,避免字段名拼写错误的问题。同样可以实现 ANDOR 的复杂组合逻辑。 例如,查询状态为“启用”且年龄大于 30,或者姓名包含 “Tom” 的用户: ```java LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>(); lambdaQueryWrapper.eq(User::getStatus, 1) .and(wrapper -> wrapper.gt(User::getAge, 30).or().like(User::getName, "Tom")); List<User> users = userMapper.selectList(lambdaQueryWrapper); ``` 生成的 SQL 为: ```sql SELECT * FROM user WHERE status = 1 AND (age > 30 OR name LIKE '%Tom%') ``` 这种方式不仅提高了代码可读性,也增强了编译时的类型安全性[^2]。 ### 3.3 嵌套条件中的 ANDOR 组合 对于更复杂的嵌套查询场景,可以使用多层 `.and()` 和 `.or()` 方法来构建条件结构。例如,查找同时满足 `(name = '张三' AND age > 30)` 或 `(name = '李四' AND age < 25)` 的记录: ```java QueryWrapper<User> wrapper = new QueryWrapper<>(); wrapper.and(wrapper1 -> wrapper1.eq("name", "张三").gt("age", 30)) .or() .and(wrapper2 -> wrapper2.eq("name", "李四").lt("age", 25)); ``` 最终生成的 SQL 为: ```sql SELECT * FROM user WHERE (name = '张三' AND age > 30) OR (name = '李四' AND age < 25) ``` 这种写法支持对多个子条件进行分组并灵活应用逻辑运算符,从而构建出高度定制化的查询条件[^1]。 ### 相关注意事项 - 在构造复杂查询条件时,应确保理解最终生成的 SQL 结构,以避免因逻辑错误导致结果偏差。 - 对于涉及动态参数的查询,建议使用 Lambda 表达式增强类型安全性。 - 测试阶段应充分验证每种条件组合的行为是否符合预期,尤其是在生产环境中使用前应进行充分测试。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值