Java通过JDBC查询INT类型含NULL字段时,必须用Integer等包装类接收,不可用基本类型int,否则 getInt() 返回0无法区分真实0与NULL,且可能抛异常;应先调用 wasNull() 判断或改用 getObject("col", Integer.class)。

Java 通过 JDBC 查询数据库时,若某列是整型(如 INT)但数据库中存在 NULL 值,而代码中用基本类型 int 接收,就会直接抛出 NullPointerException 或 SQLException。这不是“偶然暴发”,而是类型不匹配导致的确定性异常,关键在接收方式和 JDBC 映射逻辑。
确认字段是否允许为空
先查表结构,确认目标字段是否为 NULLABLE:
- MySQL:执行
DESCRIBE table_name;或SHOW COLUMNS FROM table_name;,看Null列是否为YES - SQL Server / Oracle:查
INFORMATION_SCHEMA.COLUMNS中IS_NULLABLE字段 - 如果字段允许为空,代码就不能用
int直接接收,否则 ResultSet 取值时会失败
统一改用包装类接收
MyBatis 或原生 JDBC 中,应始终用 Integer(而非 int)映射可能为空的整型字段:
- MyBatis Mapper 接口返回类型写成
Integer:@Select("SELECT status FROM order WHERE id = #{id}")Integer getStatusById(Long id); - 原生 JDBC 中使用
rs.getInt()前先判断:if (rs.wasNull()) { value = null; } else { value = rs.getInt("status"); } - 避免直接调用
rs.getInt()后立刻赋给int变量——一旦为 NULL,getInt()返回 0,但你无法区分“真是 0”还是“本该是 null”
SQL 层做空值兜底(适合简单场景)
当业务允许默认值、且不想改 Java 类型时,可在 SQL 中用函数提前转换:
- MySQL:
IFNULL(status, -1)或COALESCE(status, 0) - PostgreSQL:
COALESCE(status, 0) - SQL Server:
ISNULL(status, 0) - 注意:这样虽能避免 Java 端异常,但会丢失“空”的语义,慎用于业务强依赖空值含义的字段(如“未审核”不能等同于“0”)
JDBC URL 补充参数防底层干扰
某些驱动(如 MySQL Connector/J 8.x)对空值处理更严格,可加参数增强兼容性:
-
&serverTimezone=GMT%2B8(避免时区引发的间接空值问题) -
&nullCatalogMeansCurrent=true(部分元数据操作相关) - 非必须,但若配合
tinyInt1isBit=false或zeroDateTimeBehavior=convertToNull一起配置,可减少其他类型空值连带影响

















