在Java中,我试图从ResultSet测试空值,其中列被转换为原始int类型。

int iVal;
ResultSet rs = magicallyAppearingStmt.executeQuery(query);
if (rs.next()) {
  if (rs.getObject("ID_PARENT") != null && !rs.wasNull()) {
    iVal = rs.getInt("ID_PARENT");
  }
}

从上面的代码片段中,是否有更好的方法来做到这一点,并且我假设第二个wasNull()测试是多余的?

教育我们,谢谢


当前回答

以防有人在Kotlin编程时来到这里(就像我一样),BalusC建议的答案可以很好地工作。请注意,Short和Float在ResultSet中分别被实例化为Integer和Double,并且在调用getObject()后,我们应该将它们强制转换为正确的类型。在我的案例中,最终代码是:

when {
    propKClass.isSubclassOf(Int::class) -> rs.getObject(colName) as Int? 
    propKClass.isSubclassOf(Short::class) -> (rs.getObject(colName) as Int?)?.toShort()
    propKClass.isSubclassOf(Long::class) -> rs.getObject(colName) as Long?
    propKClass.isSubclassOf(Boolean::class) -> rs.getObject(colName) as Boolean?
    propKClass.isSubclassOf(Double::class) -> rs.getObject(colName) as Double?
    propKClass.isSubclassOf(Float::class) -> (rs.getObject(colName) as Double?)?.toFloat()
    else -> rs.getString(colName)
}

其他回答

您可以使用resultSet和具有Number类型的列名调用此方法。它将返回Integer值或null。数据库中的空值将不会返回零

private Integer getIntWithNullCheck(ResultSet rset, String columnName) {
    try {
        Integer value = rset.getInt(columnName);
        return rset.wasNull() ? null : value;
    } catch (Exception e) {
        return null;
    }
}

ResultSet的默认值。当字段值为NULL时,getInt将返回0,这也是iVal声明的默认值。在这种情况下,您的测试是完全多余的。

如果你真的想做一些不同的事情,如果字段值为NULL,我建议:

int iVal = 0;
ResultSet rs = magicallyAppearingStmt.executeQuery(query);
if (rs.next()) {
    iVal = rs.getInt("ID_PARENT");
    if (rs.wasNull()) {
        // handle NULL field value
    }
}

(编辑如下@martin评论;写的OP代码不会编译,因为iVal没有初始化)

为了方便,您可以为ResultSet创建一个包装器类,当ResultSet通常不会返回空值时,它会返回空值。

public final class ResultSetWrapper {

    private final ResultSet rs;

    public ResultSetWrapper(ResultSet rs) {
        this.rs = rs;
    }

    public ResultSet getResultSet() {
        return rs;
    }

    public Boolean getBoolean(String label) throws SQLException {
        final boolean b = rs.getBoolean(label);
        if (rs.wasNull()) {
            return null;
        }
        return b;
    }

    public Byte getByte(String label) throws SQLException {
        final byte b = rs.getByte(label);
        if (rs.wasNull()) {
            return null;
        }
        return b;
    }

    // ...

}

我认为这是多余的。rs.getObject("ID_PARENT")应该返回一个Integer对象或null,如果列值实际上是null。所以它甚至可以这样做:

if (rs.next()) {
  Integer idParent = (Integer) rs.getObject("ID_PARENT");
  if (idParent != null) {
    iVal = idParent; // works for Java 1.5+
  } else {
    // handle this case
  }      
}

只需使用ResultSet#getObject()检查字段是否为空。将-1替换为您想要的任何空大小写值。

int foo = resultSet.getObject("foo") != null ? resultSet.getInt("foo") : -1;

或者,如果你能保证你使用正确的DB列类型,从而ResultSet#getObject()真正返回一个Integer(因此不是长,短或字节),那么你也可以将它类型转换为一个Integer。

Integer foo = (Integer) resultSet.getObject("foo");