如果 Timestamp 映射到/来自数据库,则 Timestamp#equals() 失败

Posted

技术标签:

【中文标题】如果 Timestamp 映射到/来自数据库,则 Timestamp#equals() 失败【英文标题】:Timestamp#equals() fails if Timestamp is mapped to/from Database 【发布时间】:2017-06-06 01:53:11 【问题描述】:

我在我的 MS SQL 数据库中使用DATETIME 来存储日期和时间。

Java 到数据库:preparedStatement.setTimestamp(2, insertObj.getTimestamp());

数据库到 Java:selectedObj.setTimestamp(result.getTimestamp("datetime"));

在我的单元测试中将它们与insertObj.timestamp.equals(selectedObj.timestamp); 进行比较随机返回真或假。

这是一个已知问题吗?我该如何解决?

【问题讨论】:

所以您的数据库列属于这种类型:DATETIME,而您的 Java 变量属于这种类型:java.sql.Timestamp?还有什么 JDBC 驱动程序? @Basil Bourque 是的,这就是您将 DATETIME 值插入数据库的方式,JDBC 中没有“setDatetime()”或其他任何内容,JDBC 驱动程序将正确处理从时间戳到 DATETIME 的转换,它工作了一段时间,有时返回的时间戳与插入的时间戳相差 1ms (A) 你实际上并没有回答我的问题。 (B) 我熟悉 JDBC 的工作原理。 (C) 将示例数据值添加到您的问题中。 您的所有答案都可以在我的问题中找到:Microsoft SQL Server, DATETIME column, java.sql.Timestamp, Microsoft JDBC 4.2 【参考方案1】:

SQL Server DATETIME 的精度为 +/- 3 毫秒:

四舍五入到 0.000、0.003 或 0.007 秒的增量

换句话说,如果您插入一个小于第二小数.001 的值,它将被存储为.000.002.003 等,从而使等值检查失败。如果您在 Timestamp 中具有亚毫秒精度(例如,存储具有亚秒值 .0001Timestamp 将四舍五入为 .000),您也可以具有此效果,另见下文。

如果您想要更精确的存储,则需要使用精度为 100 纳秒的DATETIME2,否则您需要考虑舍入,例如检查两个值之间的绝对差是否小于 3毫秒,例如:

Math.abs(insertTimestamp.getTime() - selectedTimestamp.getTime()) < 3

请注意,java.sql.Timestamp 可以包含高达纳秒的精度(因此,如果您在DATETIME2 中存储分辨率高于 100ns 的值,您仍然会遇到此问题)。您通常具有毫秒精度,但如果使用setNanos(用于设置亚秒纳秒值)或从java.time 类之一创建,则可以获得纳秒精度。另请参阅Timestamp API 文档:

注意:此类型是java.util.Date 和单独的纳秒值的组合。 java.util.Date 组件中仅存储整数秒。小数秒 - 纳米 - 是分开的

【讨论】:

精彩的解释,谢谢!还有一个问题:SQL 中的 TIME 数据类型有类似的行为吗?我真的不需要这么精确,我只需要取回我存储的完全相同的值。 @Pali,参见documentation for time"Accuracy 100 纳秒(Informatica 中为 1 毫秒)",但是 java.sql.Time 仅具有秒精度,但您应该能够将Timestamp 设置/获取到time 字段,但您会丢失日期信息。

以上是关于如果 Timestamp 映射到/来自数据库,则 Timestamp#equals() 失败的主要内容,如果未能解决你的问题,请参考以下文章

我可以将 TIMESTAMP WITH TIME ZONE 或 TIMESTAMP WITH LOCAL TIME ZONE 映射到哪些 Java 数据类型?

如何将 TIMESTAMP 列映射到 ZonedDateTime JPA 实体属性?

怎么把impala表导入kudu

java 中的Date和Timestamp的区别

如果超过 78 个字符,则使用 TIMESTAMP 的 TO_CHAR 会引发 ORA-01877

csharp 将TimeStamp附加到文件名中 - 来自http://stackoverflow.com/questions/7898392/append-timestamp-to-a-file-n