在 MyBatis 中处理空参数(null)时,如果使用不当,确实可能会出现 NullPointerException,但只要掌握正确的方法,一般是可以避免的。下面详细说明:
一、MyBatis 中参数为 null 时的常见行为
1. 直接传入 null 会怎样?
- 如果你直接将
null作为参数传入 Mapper 方法,比如:mapper.selectByName(null);而你的 SQL 是这样写的:SELECT * FROM user WHERE name = #{name}MyBatis 会正常执行 SQL,只是将name = null带入。但 SQL 中name = null是无效的(因为应该是IS NULL才对),所以不会报错,但不会返回任何结果。
2. 如果在 <if> 标签中判断 null,但没写好,会报错吗?
<if test="name != null">
AND name = #{name}
</if>
- 这写法是对的。如果
name是 null,这段 SQL 就不会被拼接。 - 如果写错,比如:
<if test="name.length() > 0">这时候如果name是 null,就会在运行时抛出NullPointerException,因为调用了 null 的.length()。
二、避免空指针的最佳实践
- 使用
<if test="xxx != null">安全判断 null<if test="name != null"> AND name = #{name} </if> - 尽量避免对参数直接做方法调用
<!-- 不要这样写 --> <if test="name.length() > 0"> ... </if> <!-- 可以这样写 --> <if test="name != null and name != ''"> ... </if> - 使用 Map 传参,可以更灵活地控制参数存在与否
Map<String, Object> params = new HashMap<>(); params.put("name", null); - 开启日志,观察最终生成的 SQL,有助于调试 null 参数行为
三、Mapper 接口调用时传 null 有哪些影响?
单个参数为 null:
User user = mapper.getById(null);
- SQL 中用
#{id}替换,会出现id = null,逻辑上不成立,但不会报空指针。
多个参数,某一个为 null:
@Select("SELECT * FROM user WHERE id = #{id} AND name = #{name}")
User get(@Param("id") Integer id, @Param("name") String name);
- 如果
name为 null,而你没做判断,会变成name = null,不符合 SQL 语义。
四、小结
| 情况 | 是否抛出 NullPointerException |
|---|---|
| 直接传 null 到 #{param} | 不会,但 SQL 结果可能为 0 |
<if test="param != null"> | 安全 |
<if test="param.length() > 0"> 且 param 为 null | 会抛出 NPE |
| 多个参数用 @Param 时某个为 null | 不报错,但结果需小心 |




苏公网安备32021302001419号