gpt4 book ai didi

java - 错过了在 Java 8 中修复 JDBC 日期处理的机会?

转载 作者:IT老高 更新时间:2023-10-28 20:48:25 24 4
gpt4 key购买 nike

任何 Java 8 + JDBC 专家都可以告诉我以下推理是否有问题吗?而且,如果在众神的 secret 中,为什么没有这样做?

java.sql.Date 目前是 JDBC 用来映射到 DATE SQL 类型的类型,它表示没有时间、没有时区的日期。但是这个类设计得很糟糕,因为它实际上是 java.util.Date 的一个子类,它存储了一个精确的瞬间,最多可以达到毫秒。

为了在数据库中表示日期 2015-09-13,我们因此被迫选择一个时区,将该时区中的字符串“2015-09-13T00:00:00.000”解析为 java.util.Date 到获取一个毫秒值,然后从这个毫秒值构造一个 java.sql.Date,最后在准备好的语句上调用 setDate(),传递一个包含所选时区的 Calendar为了让 JDBC 驱动程序能够从这个毫秒值正确地重新计算日期 2015-09-13。通过在所有地方使用默认时区而不传递日历,这个过程变得更简单了。

Java 8 引入了 LocalDate 类,它更适合 DATE 数据库类型,因为它不是一个精确的时间点,因此不依赖于时区。而且 Java 8 还引入了默认方法,这将允许对 PreparedStatement 和 ResultSet 接口(interface)进行向后兼容的更改。

那么,我们是不是错过了清理 JDBC 中的烂摊子同时仍保持向后兼容性的大好机会? Java 8 可以简单地将这些默认方法添加到 PreparedStatement 和 ResultSet:

default public void setLocalDate(int parameterIndex, LocalDate localDate) {
if (localDate == null) {
setDate(parameterIndex, null);
}
else {
ZoneId utc = ZoneId.of("UTC");
java.util.Date utilDate = java.util.Date.from(localDate.atStartOfDay(utc).toInstant());
Date sqlDate = new Date(utilDate.getTime());
setDate(parameterIndex, sqlDate, Calendar.getInstance(TimeZone.getTimeZone(utc)));
}
}

default LocalDate getLocalDate(int parameterIndex) {
ZoneId utc = ZoneId.of("UTC");
Date sqlDate = getDate(parameterIndex, Calendar.getInstance(TimeZone.getTimeZone(utc)));
if (sqlDate == null) {
return null;
}

java.util.Date utilDate = new java.util.Date(sqlDate.getTime());
return utilDate.toInstant().atZone(utc).toLocalDate();
}

当然,同样的道理也适用于对 TIMESTAMP 类型的 Instant 的支持,以及对 TIME 类型的 LocalTime 的支持。

最佳答案

To represent the date 2015-09-13 in database, we're thus forced to choose a timezone, parse the string "2015-09-13T00:00:00.000" in that timezone as a java.util.Date to get a millisecond value, then construct a java.sql.Date from this millisecond value, and finally call setDate() on the prepared statement, passing a Calendar holding the timezone chosen in order for the JDBC driver to be able to correctly recompute the date 2015-09-13 from this millisecond value

为什么?只需调用电话

Date.valueOf("2015-09-13"); // From String
Date.valueOf(localDate); // From java.time.LocalDate

所有 JDBC 驱动程序中的行为都是正确的:没有时区的本地日期。逆运算为:

date.toString();    // To String
date.toLocalDate(); // To java.time.LocalDate

你不应该依赖 java.sql.Datejava.util.Date 的依赖,以及它因此继承了 java.time.Instant 的语义的事实。通过 Date(long)Date.getTime()

So, haven't we missed a huge opportunity to clean up the mess in JDBC while still maintaining backward compatibility? [...]

这取决于。 JDBC 4.2 spec指定您可以通过 setObject(int, localDate) 绑定(bind) LocalDate 类型, 并通过 getObject(int, LocalDate.class) 获取 LocalDate 类型,如果司机准备好了。当然,不像您建议的更正式的 default 方法那么优雅。

关于java - 错过了在 Java 8 中修复 JDBC 日期处理的机会?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32548331/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com