检查 Java ResultSet 中是否存在 null int 值

发布于 2024-09-03 08:01:51 字数 466 浏览 7 评论 0原文

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

教育我们,谢谢

In Java I'm trying to test for a null value, from a ResultSet, where the column is being cast to a primitive int type.

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

From the code fragment above, is there a better way to do this, and I assume that the second wasNull() test is redundant?

Educate us, and Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(13

请叫√我孤独 2024-09-10 08:01:51

当字段值为 NULL 时,ResultSet.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 未初始化)

The default for ResultSet.getInt when the field value is NULL is to return 0, which is also the default value for your iVal declaration. In which case your test is completely redundant.

If you actually want to do something different if the field value is NULL, I suggest:

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

(Edited as @martin comments below; the OP code as written would not compile because iVal is not initialised)

遥远的她 2024-09-10 08:01:51

另一个解决方案:

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

Another solution:

public class DaoTools {
    static public Integer getInteger(ResultSet rs, String strColName) throws SQLException {
        int nValue = rs.getInt(strColName);
        return rs.wasNull() ? null : nValue;
    }
}
逆蝶 2024-09-10 08:01:51

只需检查该字段是否为 null 或不使用 ResultSet#getObject()。将 -1 替换为您想要的任何 null 值。

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

或者,如果您可以保证使用正确的数据库列类型,以便 ResultSet#getObject() 真正返回 Integer (因此不是 Long >、ShortByte),那么您也可以将其类型转换为 Integer

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

Just check if the field is null or not using ResultSet#getObject(). Substitute -1 with whatever null-case value you want.

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

Or, if you can guarantee that you use the right DB column type so that ResultSet#getObject() really returns an Integer (and thus not Long, Short or Byte), then you can also just typecast it to an Integer.

Integer foo = (Integer) resultSet.getObject("foo");
‘画卷フ 2024-09-10 08:01:51

我认为,这是多余的。 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
  }      
}

I think, it is redundant. rs.getObject("ID_PARENT") should return an Integer object or null, if the column value actually was NULL. So it should even be possible to do something like:

if (rs.next()) {
  Integer idParent = (Integer) rs.getObject("ID_PARENT");
  if (idParent != null) {
    iVal = idParent; // works for Java 1.5+
  } else {
    // handle this case
  }      
}
空名 2024-09-10 08:01:51

你也可以简单地使用。

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

AFAIK即使它是 NULL

AFAIK you can simply use

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

even if it is NULL.

贪了杯 2024-09-10 08:01:51

只是 Java 泛型的更新。

您可以创建一个实用程序方法来从先前转换的给定 ResultSet 中检索任何 Java 类型的可选值。

不幸的是, getObject(columnName, Class) 不返回 null,而是给定 Java 类型的默认值,因此需要 2 次调用

public <T> T getOptionalValue(final ResultSet rs, final String columnName, final Class<T> clazz) throws SQLException {
    final T value = rs.getObject(columnName, clazz);
    return rs.wasNull() ? null : value;
}

在此示例中,您的代码可能如下所示:

final Integer columnValue = getOptionalValue(rs, Integer.class);
if (columnValue == null) {
    //null handling
} else {
    //use int value of columnValue with autoboxing
}

很高兴获得反馈

Just an update with Java Generics.

You could create an utility method to retrieve an optional value of any Java type from a given ResultSet, previously casted.

Unfortunately, getObject(columnName, Class) does not return null, but the default value for given Java type, so 2 calls are required

public <T> T getOptionalValue(final ResultSet rs, final String columnName, final Class<T> clazz) throws SQLException {
    final T value = rs.getObject(columnName, clazz);
    return rs.wasNull() ? null : value;
}

In this example, your code could look like below:

final Integer columnValue = getOptionalValue(rs, Integer.class);
if (columnValue == null) {
    //null handling
} else {
    //use int value of columnValue with autoboxing
}

Happy to get feedback

回忆凄美了谁 2024-09-10 08:01:51

您可以使用 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;
    }
}

You can call this method using the resultSet and the column name having Number type. It will either return the Integer value, or null. There will be no zeros returned for empty value in the database

private Integer getIntWithNullCheck(ResultSet rset, String columnName) {
    try {
        Integer value = rset.getInt(columnName);
        return rset.wasNull() ? null : value;
    } catch (Exception e) {
        return null;
    }
}
撕心裂肺的伤痛 2024-09-10 08:01:51

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

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

您还可以使用 setObject()Statement 中设置 null 值。

pstmt.setObject(pos++, null);

If you want an alternative to calling ResultSet.wasNull() you can use getObject() and cast to the correct type.

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

You can also set null values in a Statement with setObject().

pstmt.setObject(pos++, null);
溺深海 2024-09-10 08:01:51

为了方便起见,您可以围绕 ResultSet 创建一个包装类,该类在 ResultSet 通常不会返回 null 值时返回 null 值。

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;
    }

    // ...

}

For convenience, you can create a wrapper class around ResultSet that returns null values when ResultSet ordinarily would not.

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;
    }

    // ...

}
零度℉ 2024-09-10 08:01:51

以防万一有人在 Kotlin 编程时来到这里(就像我所做的那样),BalusC 建议的答案很好。请注意,ShortFloatResultSet< 中分别实例化为 IntegerDouble /code>,我们应该在调用 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)
}

Just in case someone comes here while programming in Kotlin (as I did), the answer suggested by BalusC works fine. Just be aware that Short and Float are instantiated as Integer and Double (respectively) inside ResultSet, and we should cast them to the correct type after calling getObject(). In my case the final code was:

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)
}
别理我 2024-09-10 08:01:51

在 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) }

In Kotlin I would just solve it once and be done with the issue forever with this:

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

So later you can just do this:

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

I guess if you want you could also do this too

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

So you can just do this:

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

Or better still make both methods available if you happen to be dealing with developers that can't agree on even the simplest of things.

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)

Edit: if the library is still being fussy you can finally do something like:

rs.getNullable("ID_PARENT", String::class)?.let {FOO.valueOf(it) }
神经暖 2024-09-10 08:01:51

使用 java 8,您可以这样做:

Long nVal = Optional.ofNullable(resultSet.getBigDecimal("col_name"))
                    .map(BigDecimal::longValue).orElse(null));

在这种情况下,如果 SQL 值为 NULL,则确保 nVal 将为 null(而不是零)

With java 8 you can do this:

Long nVal = Optional.ofNullable(resultSet.getBigDecimal("col_name"))
                    .map(BigDecimal::longValue).orElse(null));

In that case you ensure that the nVal will be null (and not zero) if the SQL value is NULL

氛圍 2024-09-10 08:01:51

如果您可以控制 SQL,另一种很好的检查方法是在查询本身中为 int 列添加默认值。然后只需检查该值即可。

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

SELECT NVL(ID_PARENT, -999) FROM TABLE_NAME;

然后检查

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

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

Another nice way of checking, if you have control the SQL, is to add a default value in the query itself for your int column. Then just check for that value.

e.g for an Oracle database, use NVL

SELECT NVL(ID_PARENT, -999) FROM TABLE_NAME;

then check

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

Of course this also is under the assumption that there is a value that wouldn't normally be found in the column.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文