【问题标题】:Getting the date from a ResultSet for use with java.time classes从 ResultSet 中获取日期以用于 java.time 类
【发布时间】:2015-04-21 13:19:38
【问题描述】:

有没有办法从ResultSet 中得到一个java.time(Java 8 中的新功能)兼容的时间类?

我知道您可以使用 ResultSetgetDategetTimestamp 但这些方法返回 java.sql.Date / java.sql.Timestamp 现在已弃用的对象,因此使用它们来创建似乎是不好的做法ZonedDateTime 或类似名称。

【问题讨论】:

  • java.sql.Date 等正式不被弃用(未设置弃用-javadoc-tag 或注释)。关于您的问题,查找 JDBC 4.2 - 对您的数据库的支持(实际上在大多数情况下不可用?)然后使用现有方法 setObject()getObject()

标签: java-8 resultset getdate java-time


【解决方案1】:

大多数数据库供应商还不支持JDBC 4.2。这个specification 表示新的java.time 类型,如LocalDate 将/应该使用现有方法setObject(...)getObject() 来支持。不需要和提供显式转换(无需 API 更改)。

Derby-mailing list 所述,可以手动转换缺少支持的解决方法。

类似:

LocalDate birthDate = resultSet.getDate("birth_date").toLocalDate();

如您所见,这些转换使用非弃用类型java.sql.Date 等,另请参阅javadoc

【讨论】:

  • 转换为 LocalDate 后,日期是否有可能翻转到第二天或前一天?我真的不希望我的生日因为时区问题而改变。
  • @Gert-Jan 转换 toLocalDate() 等只是在本地时区使用午夜(根据 JDBC 的要求和指定)委托给不推荐使用的方法,如 date.getYear(),请参阅源代码。如果您尝试由于 dst 更改而不存在的 INVALID 本地时间,那么您可能会观察到一些奇怪的时间向前跳跃(主要涉及 TIME- 和 TIMESTAMP-types)。否则,只要您有一个严格遵守规范的 JDBC 驱动程序,转换应该是安全的,即在本地 tz 中解释转换。
  • 嗯...使用午夜?如果日期当天没有午夜怎么办?
  • @Trejkaz 如果由于标准时间和夏季时间之间的时间差而导致午夜不存在,那么时间通常会向前跳差的大小。这是旧 Java 和新 java.time-classes 中的标准行为。例如:America/Sao_Paolo 在今年 10 月 15 日不会看到午夜,因此当天最早的当地时间是凌晨 1 点。
  • 实际上,java.time 通过调用atStartOfDay 方法完全回避了这个问题,所以毫无疑问它做了什么,而包括“午夜”在内的措辞总是让我感到好奇。跨度>
【解决方案2】:

Timestamp 上的新方法

Java 8 在 java.sql.Timestamp 类上包含新方法,用于与 java.time 对象相互转换。在 JDBC 驱动程序可以针对新数据类型更新之前,这些便捷方法是权宜之计。

DateTime 同上

java.sql.Datejava.sql.Time 类在 Java 8 中也添加了类似的 java.time 转换方法。

【讨论】:

    【解决方案3】:

    今天我们大多数人都在使用符合 JDBC 4.2 的驱动程序,与 2015 年的答案相比,这大大改善了这种情况。

    要从结果集中获取LocalDate

    LocalDate dateFromDatabase = yourResultSet.getObject(yourColumnIndex, LocalDate.class);
    

    LocalDate dateFromDatabase = yourResultSet.getObject("yourColumnLabel", LocalDate.class);
    

    ResultSet 没有添加任何新方法以使其正常工作。 getObject 方法一直存在。新事物是,从 JDBC 4.2 开始,它接受LocalDate.class 作为第二个参数并返回LocalDate。当查询返回 SQL 数据类型为 date 的列时,上述方法有效(实际上 JDBC 类型很重要,但他们倾向于同意)。

    您也可以传递其他 java.time 类型的类。并取回对应的类型。例如:

    OffsetDateTime dateTimeFromDatabase
            = yourResultSet.getObject(yourTimestampWithTimeZoneColumnIndex, OffsetDateTime.class);
    

    要使用的 java.time 类型是:

    SQL datatype            | java.time type
    ------------------------+-----------------------------------------------------------
    date                    | LocalDate
    time                    | LocalTime
    timestamp               | LocalDateTime
    timestamp with timezone | Officially OffsetDateTime; many drivers accept Instant too
    time with timezone      | OffsetTime
    

    另一方面,从 Java 到数据库(用作查询参数或存储)PreparedStatement.setObject 现在也接受上述 java.time 类型的对象。由于您传递的是一个类型的对象,因此在这种情况下不需要单独的类型参数。

    【讨论】:

      猜你喜欢
      • 2021-06-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-06
      • 2020-05-06
      相关资源
      最近更新 更多