【问题标题】:How to get a java.time object from a java.sql.Timestamp without a JDBC 4.2 driver?如何在没有 JDBC 4.2 驱动程序的情况下从 java.sql.Timestamp 获取 java.time 对象?
【发布时间】:2014-04-23 14:09:33
【问题描述】:

当通过 JDBC 4.1 或更早版本从数据库中检索 java.sql.Timestamp 时,如何获取/转换为 java.time 对象?

Postgres 的开源 JDBC 驱动程序都不兼容 JDBC 4.2,所以我正在寻找一种方法来使用 java.time 和 JDBC 4.1。

【问题讨论】:

  • 请问您为什么需要使用 java.time,这似乎是新的 1.8 类?
  • 因为 java.util.Date 和 .Calendar 是出了名的麻烦。我通常改用Joda-Time。但我一直在涉足 Java 8 中的 java.time。java.time 包的灵感来自 Joda-Time,但经过重新架构。
  • 更新: 虽然我接受 the Answer by pickypg 正确解决了我的问题的细节,但最好的解决方案是仅使用 java.time JDBC 4.2 的类,同时完全避免了麻烦的遗留 java.sql 类。直接与数据库交换 java.time 对象;不再需要转换。请参阅Answer by skrueger

标签: java datetime jdbc java-time


【解决方案1】:

旧类的新方法

通过使用 Java 8 及更高版本的驱动程序,您应该会自动在您的 java.sql.Timestamp 对象上免费获取一些方法。 java.sql.Timejava.sql.Date 都有类似的转换方法。

即从 java.sql 转换为 java.time 您正在寻找:

要走另一个方向,从 java.timejava.sql,请使用新的静态方法:

例子:

preparedStatement.setTimestamp( 2, Timestamp.from(instant) );

【讨论】:

  • 感谢您的回答和洞察力。我专注于 JDBC 驱动程序,并没有考虑查看 java.sql.Timestamp 类的新功能。
  • 仅供参考,在此答案中看到Instant 后,您可以申请ZoneOffset 以获得OffsetDateTime,或者更好的是,申请ZoneId 以获得ZonedDateTime .有关详细信息,请参阅另一个问题的 my Answermy diagram
  • 即将发布的版本应该支持 java 8 time API:jdbc.postgresql.org/documentation/head/8-date-time.html
  • 当使用 TIMESTAMP 类型的列(没有时区,我认为它等同于 LocalDateTime)时,JDBC 将使用哪个时区将该 TIMESTAMP 转换为瞬间?
  • 如果您将时间戳存储到数据库中,您应该将它们存储为 UTC。否则,我认为你是对的。看到这个setTimestamp answer for more details
【解决方案2】:

无需转换

就像其他人在 cmets 中所说的那样,PostgreSQL 的 JDBC 驱动程序现在支持 JDBC 4.2,包括 Java 8 Time API 支持。我们可以直接与数据库交换 java.time 对象。

https://jdbc.postgresql.org/documentation/head/8-date-time.html

因此无需转换,也无需再次使用 java.sql 类型。仅在 java.time 包中使用它们的替代品,如此列表所示。

PostgreSQL™                      Java SE 8 (java.time)
DATE                             LocalDate
TIME [ WITHOUT TIMEZONE ]        LocalTime
TIMESTAMP [ WITHOUT TIMEZONE ]   LocalDateTime
TIMESTAMP WITH TIMEZONE          OffsetDateTime or Instant

这可以通过ResultSet::getObject检索

ResultSet rs = ...;
while (rs.next()) {
  LocalDate localDate = rs.getObject(1, LocalDate.class));
}

通过调用PreparedStatement::setObject 存储一个java.time 对象。

myPreparedStatement.setObject( … , myInstant ) ; 

【讨论】:

  • 这个答案是一个非常重要的更新。只坚持 java.time 类确实是要走的路。
猜你喜欢
  • 2012-05-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-26
  • 1970-01-01
  • 2017-01-25
  • 2021-01-29
  • 1970-01-01
相关资源
最近更新 更多