有没有办法从ResultSet
中获取一个与Java 8中的新类java.time
兼容的时间类?
我知道你可以使用ResultSet
的 getDate
或 getTimestamp
方法,但是这些方法返回的是已经过时的java.sql.Date
/ java.sql.Timestamp
对象,因此似乎不好的做法是使用它们来创建ZonedDateTime
或类似对象。
toLocalDate()
等只是委托给已弃用的方法,如 date.getYear()
,使用本地时区中午(根据 JDBC 所需和指定的要求),请参见源代码。如果您尝试一个无效的本地时间,由于 DST 更改而不存在,则可能会观察到一些奇怪的时间向前跳跃(主要涉及 TIME 和 TIMESTAMP 类型)。否则,只要您有一个严格遵守规范的 JDBC 驱动程序,即在本地 tz 中解释转换,转换就应该是安全的。 - Meno Hochschildjava.time
类的标准行为。例如:美洲/圣保罗将不会在今年10月15日看到午夜,因此当天最早的本地时间将是上午1点。 - Meno Hochschildjava.time
通过调用方法atStartOfDay
完全避开了这个问题,因此它的作用是毋庸置疑的,而包括“午夜”在内的措辞总是让我感到困惑。 - Hakanai今天,我们大多数人都在使用符合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类型的对象。由于您正在传递类型的对象,因此在执行此操作时无需单独的类型参数。
Timestamp
的新方法Java 8在java.sql.Timestamp
类中添加了一些新方法,用于转换成和从java.time对象中获取。这些便捷方法是一种临时措施,直到JDBC驱动程序可以更新为新的数据类型。
Date
和Time
也是如此在Java 8中,java.sql.Date
和java.sql.Time
类也添加了类似的java.time转换方法。
setObject()
和getObject()
方法。 - Meno Hochschild