为什么 queryForObject Kotlin 扩展 func returns 可为空 T?它是否真的会抛出 EmptyResultDataAccessException?
Why queryForObject Kotlin extension func returns nullable T? if it actually will throw EmptyResultDataAccessException?
使用 Kotlin 和 Spring 5 进行一些简单的项目。
我想使用 queryForObject
通过 id 从数据库中获取单个记录。
我的查询是 'simple select by id':
jdbc.queryForObject("select id, name from example where id = ?", id)
{ rs: ResultSet, _: Int -> NamedEnt(rs.getLong("id"), rs.getString("name") }
在 JdbcOperationsExtensions.kt
中声明为 return 可空类型 T?
:
fun <T : Any> JdbcOperations.queryForObject(sql: String, vararg args: Any, function: (ResultSet, Int) -> T): T? =
queryForObject(sql, RowMapper { resultSet, i -> function(resultSet, i) }, *args)
实际上,当我传递不存在的标识符时,我面临:
org.springframework.dao.EmptyResultDataAccessException: Incorrect result size: expected 1, actual 0
那我不明白 returning 可空类型有什么意义?您要么收到一条记录,要么收到异常。或者我错过了什么?
JdbcOperationsExtensions.kt
在org.springframework.jdbc.core.JdbcOperations
接口上增加了一些扩展功能(写在Java)。如果您查看 Java 中 queryForObject
的文档,它会显示:
@return the single mapped object (may be {@code null} if the given
{@link RowMapper} returned {@code} null)
有关 JdbcOperations
Java class.
的完整源代码,请参阅 here
因此 Kotlin 编写的扩展函数需要遵守这一点并允许 returned 空值,因此是可空类型。
除了...正如@AlexeyRomanov 指出的那样,queryForObject
的这种特殊重载接受了一个 returns T
的 lambda,所以永远 [=40] =] null,所以可以说这个重载可以 return T
,而不是 T?
。也许 Kotlin 中的这个 lambda 不能 return null 有点不一致,但是 JavaDocs on the very similar overload in the Java class 明确指出它( RowMapper
) 应该被允许为 return null。
不管那一点,queryForObject
的一些其他重载只是调用到 Java 写的重载,因为它是写在 Java 中的,所以它可能可以return 一个空值。所以对于他们来说,它是一个可以为 null 的 return 值似乎是有意义的。在这种情况下,可以说所有重载实际上 return 可空 T
.
的一致性很好
使用 Kotlin 和 Spring 5 进行一些简单的项目。
我想使用 queryForObject
通过 id 从数据库中获取单个记录。
我的查询是 'simple select by id':
jdbc.queryForObject("select id, name from example where id = ?", id)
{ rs: ResultSet, _: Int -> NamedEnt(rs.getLong("id"), rs.getString("name") }
在 JdbcOperationsExtensions.kt
中声明为 return 可空类型 T?
:
fun <T : Any> JdbcOperations.queryForObject(sql: String, vararg args: Any, function: (ResultSet, Int) -> T): T? =
queryForObject(sql, RowMapper { resultSet, i -> function(resultSet, i) }, *args)
实际上,当我传递不存在的标识符时,我面临:
org.springframework.dao.EmptyResultDataAccessException: Incorrect result size: expected 1, actual 0
那我不明白 returning 可空类型有什么意义?您要么收到一条记录,要么收到异常。或者我错过了什么?
JdbcOperationsExtensions.kt
在org.springframework.jdbc.core.JdbcOperations
接口上增加了一些扩展功能(写在Java)。如果您查看 Java 中 queryForObject
的文档,它会显示:
@return the single mapped object (may be {@code null} if the given
{@link RowMapper} returned {@code} null)
有关 JdbcOperations
Java class.
因此 Kotlin 编写的扩展函数需要遵守这一点并允许 returned 空值,因此是可空类型。
除了...正如@AlexeyRomanov 指出的那样,queryForObject
的这种特殊重载接受了一个 returns T
的 lambda,所以永远 [=40] =] null,所以可以说这个重载可以 return T
,而不是 T?
。也许 Kotlin 中的这个 lambda 不能 return null 有点不一致,但是 JavaDocs on the very similar overload in the Java class 明确指出它( RowMapper
) 应该被允许为 return null。
不管那一点,queryForObject
的一些其他重载只是调用到 Java 写的重载,因为它是写在 Java 中的,所以它可能可以return 一个空值。所以对于他们来说,它是一个可以为 null 的 return 值似乎是有意义的。在这种情况下,可以说所有重载实际上 return 可空 T
.