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

我知道java.sql.Date应该将小时,分钟,秒和毫秒设置为零,以符合标准SQL日期的定义.这记录在here(Java 8中相同).

我也知道Oracle DATE type确实有YEAR,MONTH,DAY,HOUR,MINUTE和SECOND这些时间字段.但没有分数秒和时区.

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

private static final String REQUETE_LISTE_CALENDRIER_DATE = 
    " SELECT ID_DATE,JOUR" +
    " FROM CALENDRIER " +
    " WHERE ID_DATE = ? ";

绑定到PreparedStatement的java.sql.Date“dateCourante”定义如下(它将值设置为那些时间字段):

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,我没有.

在我的数据库中,日期的小时,分​​钟,秒为零.我们可以查看以下查询:

select to_char(id_date,'DD/MM/YYYY HH24:MI:SS')
from calendrier
where id_date = to_date('26/08/2016','DD/MM/YYYY');

这给了:

26/08/2016 00:00:00

所以,我的理解是:

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

我无法找到有关此行为的文档.

任何人都可以确认或解释吗?

作为解决方法,我使用它,如here所述:
dDate = java.sql.Date.valueOf(dDate.toLocalDate()); //其中dDate是java.sql.Date

最佳答案
虽然我没有解释,但是说很多人用最新一代的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.Date,java.util.Calendar,java.util.GregorianCalendar,java.text.DateFormat,java.text.SimpleDateFormat.如果可能的话,也要避免使用java.sql类型.而是使用java.time类.

JDBC 4.2

从JDBC 4.2开始,您的JDBC驱动程序可能能够直接从您的数据库访问java.time类型. PreparedStatement :: setObject和ResultSet :: getObject方法可能能够将数据库中的日期时间值作为java.time对象呈现.

Instant instant = myResultSet.getObject( 1 );

…也许…

Instant instant = myResultSet.getObject( 1,Instant.class );

如果您的驱动程序不那么强大,那么请简单地转换为java.sql类型并立即转换为java.time.使用java.time完成所有业务逻辑.仅适用于与数据库交换数据的java.sql类型.要转换为/从java.time,请查找添加到旧类的新方法.例如,java.sql.Timestamp::toInstant.

这里我们从ResultSet中提取java.sql.Timestamp并立即将其转换为Instant.您可能希望在两行而不是一条组合行上执行此操作以进行调试.

Instant instant = myResultSet.getTimestamp( 1 ).toInstant();

相关文章

摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠...
摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠...
今天犯了个错:“接口变动,伤筋动骨,除非你确定只有你一个...
Writer :BYSocket(泥沙砖瓦浆木匠)微 博:BYSocket豆 瓣:...
本文目录 线程与多线程 线程的运行与创建 线程的状态 1 线程...