在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()测试是多余的?

教育我们,谢谢


当前回答

如果你想要一个替代调用ResultSet.wasNull()的方法,你可以使用getObject()并强制转换为正确的类型。

Long val = (Long)rs.getObject(pos++);

你也可以用setObject()在语句中设置空值。

pstmt.setObject(pos++, null);

其他回答

另一种很好的检查方法是,如果您控制了SQL,则在查询本身中为int列添加一个默认值。然后检查这个值。

例如,对于Oracle数据库,使用NVL

SELECT NVL(ID_PARENT, -999) FROM TABLE_NAME;

然后检查

if (rs.getInt('ID_PARENT') != -999)
{
}

当然,这也是在假设有一个值通常不会在列中找到的前提下。

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

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

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

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

我想你可以简单地使用

iVal = rs.getInt("ID_PARENT");
if (rs.wasNull()) {
  // do somthing interesting to handle this situation
}

即使它是NULL。

另一个解决方案:

public class DaoTools {
    static public Integer getInteger(ResultSet rs, String strColName) throws SQLException {
        int nValue = rs.getInt(strColName);
        return rs.wasNull() ? null : nValue;
    }
}

在Kotlin中,我只会解决它一次,并永远解决这个问题:

fun <K : Any> ResultSet.getNullable(columnLabel: String, type: KClass<K>): K? = 
    this.getObject(columnLabel, type.java)

之后你可以这样做:

rs.getNullable("ID_PARENT", Int::class)

我想如果你愿意,你也可以这样做

fun <K> ResultSet.getNullable(columnLabel: String, type: Class<K>): K? = 
    this.getObject(columnLabel, type)

所以你可以这样做:

rs.getNullable("ID_PARENT", Int::class.java)

如果你遇到的开发人员连最简单的事情都不能达成一致,最好还是同时提供两种方法。

fun <K : Any> ResultSet.getNullable(columnLabel: String, type: KClass<K>): K? =
        this.getNullable(columnLabel, type.java)

fun <K> ResultSet.getNullable(columnLabel: String, type: Class<K>): K? =
        this.getObject(columnLabel, type)

编辑:如果库仍然是挑剔的,你终于可以这样做:

rs.getNullable("ID_PARENT", String::class)?.let {FOO.valueOf(it) }