为什么queryForObject Kotlin扩展func返回可为空的T?是否实际上会抛出EmptyResultDataAccessException?

时间:2019-03-25 14:54:10

标签: kotlin spring-jdbc spring-kotlin

使用Kotlin和Spring 5进行一些简单的项目。 我想使用__HAL_RCC_GPIOB_CLK_ENABLE(); /**I2C1 GPIO Configuration PB9 ------> I2C1_SDA PB8 ------> I2C1_SCL */ GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_8; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; // standard GPIO_MODE_AF_OD => GPIO_MODE_AF_PP (open drain mode to push pull mode ) GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF4_I2C1; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); /* Peripheral clock enable */ __HAL_RCC_I2C1_CLK_ENABLE(); 通过ID从数据库获取单个记录。 我的查询是“按ID简单选择”:

queryForObject

jdbc.queryForObject("select id, name from example where id = ?", id) { rs: ResultSet, _: Int -> NamedEnt(rs.getLong("id"), rs.getString("name") } 中,它声明返回可空类型JdbcOperationsExtensions.kt

T?

实际上,当我传递不存在的标识符时,我会面对:

  

org.springframework.dao.EmptyResultDataAccessException:错误的结果大小:预期为1,实际为0

那么我不明白返回可空类型的意义是什么?您会收到一条记录或例外。还是我想念什么?

1 个答案:

答案 0 :(得分:1)

def is_merge(s, p1, p2, cache=None): if cache is None: cache = {} key = s, frozenset((p1, p2)) if key not in cache: cache[key] = \ p1 and p1[0] == s[0] and is_merge(s[1:], p1[1:], p2, cache) or \ p2 and p2[0] == s[0] and is_merge(s[1:], p1, p2[1:], cache) or \ False if s else not p1 and not p2 return cache[key] JdbcOperationsExtensions.kt接口(用Java编写)添加了一些扩展功能。如果您在其中查看org.springframework.jdbc.core.JdbcOperations的JavaDoc,它会说:

queryForObject

有关@return the single mapped object (may be {@code null} if the given {@link RowMapper} returned {@code} null) Java类的完整源代码,请参见here

因此Kotlin编写的扩展功能必须遵守这一点,并允许返回null,因此可以为null。

除了...如@AlexeyRomanov所指出的那样,JdbcOperations的这种特殊重载采用了一个返回queryForObject的lambda,因此永远不能返回null,因此可以说这种重载可以返回{ {1}},而不是T。 Kotlin中的此lambda不能返回null可能有点不一致,但是Java类中非常相似的重载的JavaDocs明确声明应允许它(T)返回null。

无论如何,T?的其他一些重载都只是调用Java编写的重载,并且由于它是用Java编写的,因此有可能返回null。因此,对于他们来说,将其作为可为空的返回值似乎确实有意义。在这种情况下,所有重载实际上都返回可为空的RowMapper可以说是很好的一致性。