之前写过一篇关于 in 与 not in 问题的文章(结合 Mybatis,探讨 Oracle 中 in 与 not in 的陷阱),现在在扩展一下,谈谈 Mybatis Plus 单表操作时 in(not in) 的相关问题。
先用一个简单的例子说明下问题,比如我们要查一年级所有同学的信息。经常会有下面这样的写法:
// 获取班级ID集合
List<String> classIdList = classMapper.selectList().stream()
.map(Class::getClassId)
.collect(Collectors.toList());
// 获取学生信息
List<Student> studentList = studentMapper.selectList(
new QueryWrapper<Student>().lambda()
.in(Student::getClassId, classIdList)
);
这样的写法,咋一看没什么问题。开发人员在开发过程中,也没发现问题,因为语句能执行,查询有数据。但是到了测试的时候,问题就来了。只是查一年级学生的数据,结果把全校的学生都查出来了。
会出现这样的问题,原因有两个:
- 查询出来的 classIdList 数据为空。
- 查询学生信息时,in 条件失效。
之所以有这样的问题出现,是开发人员在开发过程中有以下一些误区:
误区一:查询语句必定能取到数据。
对于初学者,甚至工作一段时间的开发人员都会有这么一个误区,自己写好的查询语句一定是对的,而且一定能查出数据。会有这样自我感觉良好的情况出现,原因来自于开发的模式。在做功能开发的时候,一开始数据库是没有任何数据的,需要开发人员手动录入。而为了使功能可以正常运行,开发人员录入的数据会保证每个方法都能得到相应的结果,即查询的时候有值。这就导致了开发过程中容易漏掉查询无数据的情况。
误区二:查询语句的条件必定生效。
在上面的例子中,因为 classIdList 为空,Mybatis Plus 在组装 SQL 语句时,是不会把 in 这个条件拼接进来的,从而导致查询语句时没有 in 这个约束条件的。即,当条件 in 中的数组为空时(classIdList 为空),in 是无效的。
避免再次产生类似的问题,也有比较简单的处理办法。即,凡是查询语句,均对查询结果进行判断。
将例子中的代码修改为比较正确的形式,示例如下:
// 获取班级ID集合
List<String> classIdList = classMapper.selectList().stream()
.map(Class::getClassId)
.collect(Collectors.toList());
if (classIdList.isEmpty()) {
return new ArrayList<>();
}
// 获取学生信息
List<Student> studentList = studentMapper.selectList(
new QueryWrapper<Student>().lambda()
.in(Student::getClassId, classIdList)
);
以上就是本文的全部内容,希望对大家有帮助。
如果文章有帮助到了你,欢迎点赞、转发。
如果文章有错误的地方,欢迎留言交流。