如何在JDBC中从resultSet读取可能为null的double值?

39

我在数据库中有一列类型为double的数据。我希望使用JDBC ResultSet读取该列的值,但它可能为空。请问最好的方法是什么?我想到了三种选项,但都不太好。

选项1:不好,因为异常处理冗长且难闻。

double d;
try {
   d = rs.getDouble(1);
   // do something
} catch(SQLException ex) {
   if(rs.wasNull()) {
      // do something else
   } else {
     throw ex;
   }
}

选项2:不好,因为需要进行两次获取

s = rs.getString(1); // or getObject()
if(s == null) {
  // do something else
} else {
  double d = rs.getDouble(1);
  // do something
}

选项3:不好,因为需要将Java转换为SQL

s = rs.getString(1); // or getObject()
if(s == null) {
  // do something else
} else {
  double d = Double.parseDouble(s);
  // do something
}

有没有关于哪种方式更好的建议,或者有没有其他更好的方法?请不要说“使用Hibernate”,因为这里我只能使用JDBC代码。

5个回答

61

选项1最接近:

double d = rs.getDouble(1);
if (rs.wasNull()) {
  // do something
} else {
  // use d
}

这并不是很好,但这就是JDBC。如果列为空,则该双精度值被认为是“不好的”,因此每次读取在数据库中可为空的基元时,您都应该使用wasNull()进行检查。


2
注意,从结果集中检索空原始类型时没有sqlexception。在这种情况下返回该原始类型的默认值(int为0,double为0.0等)。这就是为什么.wasNull()是必要的恶。 - Matt
1
当我意识到普通的JDBC在处理null值时的工作方式时,我的反应与@JosefPfleger完全相同。如果您想继续使用纯SQL(而不是采用ORM)并避免这种混乱,我建议使用Spring的JdbcTemplate,它会为您处理所有繁琐的null检查。 - Priidu Neemre

19

根据您的JDBC驱动程序和数据库,您可以使用包装类型并进行强制转换:

Double doubleValueOrNull = (Double)rs.getObject(1); // or .getObject("columnName")

如果该列为NULL,则它将为null

注意,如果更改了数据库,请仔细检查这仍然是否有效。


当我使用Oracle语法查询HSQLDB进行测试时,这个方法对我不起作用。 - sravanreddy001
在MySQL中,这对我很管用,而且比.wasNull()更好看。 - Hugo Zaragoza

9

使用:

rs.getObject(1)==null?null:rs.getBigDecimal(1).doubleValue()

8

或者在Java 8中,您可以这样做:

Double dVal = Optional.ofNullable(resultSet.getBigDecimal("col_name"))
                .map(BigDecimal::doubleValue).orElse(null));

0

检索可为空字段的 Kotlin 版本:

val parentId = resultSet.getObject("parent_id") as Double?

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接