关键是要用setnull()显式设置sql null,而非传java null;需按字段类型匹配types.varchar等sql类型,并根据对象属性是否为null动态选择setstring()或setnull()。

在 PreparedStatement 中安全处理 NULL 值,关键不是“避免传 NULL”,而是**显式告知 JDBC 驱动该参数应被设为 SQL NULL**——必须用 setNull() 方法,不能直接传 Java 的 null(否则多数驱动会报错或行为未定义)。
用 setNull() 显式设置 NULL
PreparedStatement 不允许对参数直接调用 setXXX(?, null)(比如 setString(1, null) 在某些驱动中会抛 SQLException)。正确做法是:
- 先调用
setNull(int parameterIndex, int sqlType),指定参数位置和对应的 SQL 类型 - SQL 类型需与数据库字段类型匹配,常用如:
Types.VARCHAR、Types.INTEGER、Types.DATE、Types.TIMESTAMP - 示例:给 VARCHAR 字段设 NULL
ps.setNull(1, Types.VARCHAR);
配合对象判空,动态选择 setXXX 或 setNull
实际业务中,参数常来自对象属性(如 User.getName()),需先判断是否为 null 再决定调用哪个方法:
- 非 null → 调用对应
setXXX()(如setString()) - 为 null → 调用
setNull()并传入正确 SQL 类型 - 示例:
String name = user.getName();<br> if (name == null) {<br> ps.setNull(1, Types.VARCHAR);<br> } else {<br> ps.setString(1, name);<br> }
注意数据库类型与 SQL 类型的映射
不同数据库对同一字段可能有不同底层类型,但 JDBC 定义了标准 SQL 类型。常见映射关系:
- MySQL
VARCHAR/ PostgreSQLTEXT/ OracleVARCHAR2→Types.VARCHAR - MySQL
INT/ PostgreSQLINTEGER/ OracleNUMBER(10)→Types.INTEGER - PostgreSQL
JSONB或 MySQL 5.7+JSON→ 通常用Types.LONGVARCHAR或厂商扩展类型(需查驱动文档) - 不确定时,可参考
DatabaseMetaData.getTypeInfo()查询数据库支持的类型
小技巧:封装工具方法简化重复逻辑
为减少样板代码,可封装一个通用方法:
public static void setNullableString(PreparedStatement ps, int index, String value) throws SQLException {<br> if (value == null) ps.setNull(index, Types.VARCHAR);<br> else ps.setString(index, value);<br> }- 类似地可写
setNullableInt()、setNullableTimestamp()等 - 使用时更清晰:
setNullableString(ps, 1, user.getName());
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











