首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java 8中的java.sql.Date与Java 6相比

Java 8中的java.sql.Date与Java 6相比
EN

Stack Overflow用户
提问于 2016-08-26 12:17:27
回答 2查看 2K关注 0票数 5

我知道,java.sql.Date应该将小时、分钟、秒和毫秒设置为零,以符合标准SQL的定义。这是文档化的这里 (在Java8中也是如此)。

我还知道,Oracle日期类型 ,这些时间字段是年、月、日、小时、分钟和秒。但没有分数秒也没有时区。

我注意到Java 6和Java 8中的相同查询的行为并不相同:

代码语言:javascript
复制
private static final String REQUETE_LISTE_CALENDRIER_DATE = 
    " SELECT ID_DATE, JOUR" +
    " FROM CALENDRIER " +
    " WHERE ID_DATE = ? ";

将这样定义的PreparedStatement绑定到java.sql.Date "dateCourante“(为这些时间字段设置值):

代码语言:javascript
复制
GregorianCalendar gregorianCalendar = new GregorianCalendar(); // "now"
java.sql.Date dateCourante = new java.sql.Date(gregorianCalendar.getTime().getTime()); // date AND time of "now"
  • 使用Java 6,我找到一个值,
  • 使用Java 8,我没有。

在我的数据库中,日期有小时、分钟、秒到零。我们可以使用以下查询进行检查:

代码语言:javascript
复制
select to_char(id_date, 'DD/MM/YYYY HH24:MI:SS')
from calendrier
where id_date = to_date('26/08/2016', 'DD/MM/YYYY');

这意味着:

2016年08月26日00:00:00

所以,我所了解的是:

  • 在Java 6中,在数据库上启动查询之前,java.sql.Date的时间字段设置为零,而
  • 在Java8中,java.sql.Date的时间字段保留在查询中。

我还没有找到关于这种行为的文档。

有人能证实或解释吗?

作为解决办法,我使用了这样的方法,如解释的这里:dDate = java.sql.Date.valueOf(dDate.toLocalDate());//其中dDate是java.sql.Date

EN

回答 2

Stack Overflow用户

发布于 2016-09-03 21:47:28

虽然我没有任何解释,除了说许多人报告了最近几代Oracle驱动程序存在的问题和违反JDBC的情况,但我可以说您滥用了这些类。还有更好的课程。

java.sql.Date仅限日期。

您在Java端选择了错误的类。虽然java.sql.Date类在其内部的UTC中确实有一个时间设置为00:00:00,但是您应该按照类文档的指示忽略这个事实。java.sql.Date 用于仅用于日期的值,没有一天的时间,也没有时区。

这个类是一个糟糕的设计,是一个糟糕的黑客,是从java.util.Date继承的,同时告诉您忽略继承事实。

java.sql.Timestamp是日期和时间

java.sql.Timestamp是在您的情况下需要的类型,而不是java.sql.Date。(但为了更好的课堂继续读下去。)

Java早期版本中的所有旧日期时间类是一个勇敢的行业--首次尝试解决日期时间处理问题,但它们都失败了。它们的设计很差,令人困惑,也很麻烦。避开他们:java.util.Datejava.util.Calendarjava.util.GregorianCalendarjava.text.DateFormatjava.text.SimpleDateFormat。如果可能的话,也避免使用java.sql类型。相反,请使用java.time类。

JDBC 4.2

从JDBC4.2开始,您的JDBC驱动程序可能可以直接从数据库访问java.time类型。PreparedStatement::setObjectResultSet::getObject方法可以将数据库中的日期时间值呈现为java.time对象。

代码语言:javascript
复制
Instant instant = myResultSet.getObject( 1 );

…或者也许是…

代码语言:javascript
复制
Instant instant = myResultSet.getObject( 1 , Instant.class );

如果您的驱动程序没有这样的能力,那么请简要地转换为java.sql类型,然后立即自己转换为java.time。使用java.time执行所有业务逻辑。使用java.sql类型仅用于与数据库交换数据。要转换到/从java.time,请查找添加到旧类中的新方法。例如,java.sql.Timestamp::toInstant

在这里,我们从java.sql.Timestamp中提取一个ResultSet,并立即将其转换为Instant。为了调试目的,您可能需要在两行而不是一条合并行上执行此操作。

代码语言:javascript
复制
Instant instant = myResultSet.getTimestamp( 1 ).toInstant();
票数 3
EN

Stack Overflow用户

发布于 2016-09-03 14:01:53

Java 8还为其他一些常见用例提供了类。

YearMonth

有一个MonthDay类,它包含一个月和一个工作日。对代表生日很有用。

MonthDay

YearMonth类包括信用卡开始日期和到期日期、用例和方案,在这些情况下,人们没有指定的日期。

JDBC 4.2

Java 8中的JDBC将支持这些新类型,但不会发生公共JDBC更改。现有的泛型setObject和getObject方法就足够了。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39166170

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档