MyBatis-Plus Wrappers.ne 空指针异常排查与解决
在使用 MyBatis-Plus 的 Wrappers.ne() 时,如果直接传入 classroom.getId(),即使通过前缀参数控制是否生成 SQL,依然会触发空指针异常。这是因为 Java 在传递参数时会先计算表达式的值,此时对象尚不可用。
错误示例:参数求值导致的 NPE
以下是典型的引发异常的代码片段:
Classroom classroom = this.getOne(
Wrappers.<Classroom>lambdaQuery()
.select(Classroom::getId, Classroom::getJoinType)
.eq(Classroom::getClassId, signupSubmitVO.getClassId())
.eq(Classroom::getUserId, userId)
);
// 当 classroom 为 null 时,下方语句报错
List<Classroom> list = this.list(
Wrappers.<Classroom>lambdaQuery()
.select(Classroom::getId, Classroom::getProvinceId)
.eq(Classroom::getClassId, signupSubmitVO.getClassId())
// 问题所在:即使前面的条件为假,getId() 依然被执行
.ne(classroom != null, Classroom::getId, classroom.getId())
);开发者的初衷是利用 ne(boolean condition, R column, Object val) 中的布尔参数来控制条件是否加入最终的 SQL 中。然而,condition 仅决定生成的 SQL 字符串中是否包含该 WHERE 子句,并不阻止方法的执行过程。
原理解析
查看底层源码逻辑可知,该方法接受 Object val 作为值参数。在调用 .ne() 时,Java 虚拟机必须先计算实参 classroom.getId() 的值,然后再将其传递给方法。由于此时 classroom 尚未通过安全判断,获取其 ID 必然抛出 NullPointerException。
解决方案:前置独立判断
要规避此问题,必须将逻辑拆分为两步:先处理业务数据,再通过判断追加动态条件。
Classroom classroom = this.getOne(
Wrappers.<Classroom>lambdaQuery()
.select(Classroom::getId, Classroom::getJoinType)
.eq(Classroom::getClassId, signupSubmitVO.getClassId())
.eq(Classroom::getUserId, userId)
);
if (joinType == null && classroom != null) {
joinType = classroom.getJoinType();
}
// 重构后的查询逻辑
LambdaQueryWrapper<Classroom> query = Wrappers.<Classroom>lambdaQuery()
.select(Classroom::getId, Classroom::getProvinceId, Classroom::getCityId, Classroom::getAreaId)
.eq(Classroom::getClassId, signupSubmitVO.getClassId());
// 只有在对象不为 null 时才追加排除条件
if (classroom != null) {
query.ne(Classroom::getId, classroom.getId());
}虽然代码量稍有增加,但遵循了 Java 的基础语义规范,彻底解决了运行时异常。在处理动态 SQL 过滤时,务必注意:**任何涉及对象属性提取的操作,必须在参数传递前完成空值校验**。
以上就是MyBatis-Plus之Wrappers.ne踩坑记录解决的详细内容,更多关于MyBatis-Plus Wrappers.ne踩坑的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









