文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Java 8日期与数据库日期的映射关系是什么

2023-06-26 07:47

关注

Java 8日期与数据库日期的映射关系是什么,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

Java8中有很多新型的日期类型,比传统的日期类型好用。使用什么和数据库的日期进行映射,却是一个比较复杂的问题。

JDBC 4.2 规范

根据JDBC4.2的规范,Java日期类型和数据库日期类型关系如下:

Java 日期数据库日期
java.sql.DateDATE
java.sql.TimeTIME
java.sql.TimestampTIMESTAMP
java.util.CalendarTIMESTAMP
java.util.DateTIMESTAMP
java.time.LocalDateDATE
java.time.LocalTimeTIME
java.time.LocalDateTimeTIMESTAMP
java.time.OffsetTimeTIME_WITH_TIMEZONE
java.time.OffsetDatetimeTIMESTAMP_WITH_TIMEZONE

有两个是比较特别的。

java8中新的日期类型代替旧日期类型

注意:JDBC4.2规范不支持Instant和ZonedOffsetDateTime

PostgreSQL JDBC 实现

Java 日期数据库日期
java.time.LocalDateDATE
java.time.LocalTimeTIME[ WITHOUT TIME ZONE ]
java.time.LocalDateTimeTIMESTAMP [ WITHOUT TIME ZONE ]
java.time.OffsetDatetimeTIMESTAMP WITH TIME ZONE

除了不支持Instant和ZonedOffsetDateTime外,OffsetTime也不支持。

参考:PostgreSQL JDBC: Using Java 8 Date and Time classes

PostgreSQL 数据库

timestamp类似LocalDateTime,只是本地时间。要确保JVM的时区和数据库的时区一致,否则会出现时差。

timestamptz是TIMESTAMP WITH TIME ZONE类型,但并没有保存 Time Zone 信息,只是简单的使用UTC标准时间。理由是Time Zone只用于显示,而如何显示时间应该由应用程序处理,没有必要保存到数据库中。

mysql-">MySQL 数据库

MySQL甚至没有提供TIMESTAMP WITH TIME ZONE的类型,日期时间类型只有DateTime,没有 Time Zone 概念。必须使用jdbc连接中的serverTimezone确定时区。如jdbc:mysql://localhost/ujcms?serverTimezone=Asia/Shanghai。

Oracle 数据库

Date:本地时间。精度到秒。
Timestamp:本地时间。精度可以到纳秒。
TIMESTAMP WITH TIME ZONE:标准的OffsetDateTime,保存有Time Zone 信息。
TIMESTAMP WITH LOCAL TIME ZONE:和PostgresSQL的timestamptz类似,只保存标准的UTC时间,然后根据本地的 Time Zone 进行计算。

SQL Server 数据库

datetime2:本地时间。
datetimeoffset:标准的OffsetDateTime,保存有 Time Zone 信息。

JPA

JPA对日期的支持于JDBC规范是一致的。

Hibernate

Hibernate在JPA的基础上进行了扩展,支持Instant、ZonedDateTime。

但所有的Java8日期类型最后都转换成Timestamp进行处理。也就是说即使数据库支持TIMESTAMP WITH TIME ZONE并保存了时区信息,Hibernate也会将其丢弃,转而使用JVM的时区(时间是确保正确的)。

MyBatis

支持Instant。转为Timestamp处理。

支持ZonedDateTime,直接使用原生的。兼容性差,如PostgreSQL JDBC不支持这种类型的,会报错。

Freemarker

使用freemarker-java-8进行格式化。

支持OffsetDateTime和ZonedDateTime的格式化,使用对象中自带的时区。

不支持Instant格式化,会直接调用toString()方法。官方说会增加Instant的支持,但已经3年没有发布新版本。

Thymeleaf

支持OffsetDateTime和ZonedDateTime的格式化,使用对象中自带的时区。

支持Instant格式化,使用JVM默认时区。

Jackson

如何选择

LocalDateTime虽然日期显示友好,但时区不确定,取决于JVM的时区。这导致时间也不确定,不同时区的JVM访问数据库,会得到不一样的时间。这非常致命,使用LocalDateTime一定要确保JVM和数据库的时区一致。

按照JDBC规范,毫无疑问应该选择OffsetDateTime。OffsetDateTime是一个好选择,具有像LocalDateTime一样直观友好的日期显示,又能确保时间的确定性。

但由于MySQL和PostgreSQL都没有提供真正的保存时区的TIMESTAMP WITH TIME ZONE,OffsetDateTime其实已经降级为Instant(PostgresSQL的timestamptz本质上就是Instant)。特别是PostgreSQL提供的是一个标准UTC时区,而实际需要的是UTC+8的北京时间,这导致在Freemarker和Thymeleaf中都无法得到正确的格式化。

考虑到数据库兼容性的问题,Instant似乎是一个更好的选择。但JDBC4.2及JDBC4.3都不支持Instant,且Instant在Freemarker中也无法格式化。

大部分数据库都提供真正的TIMESTAMP WITH TIME ZONE,即使是MySQL也能通过设置serverTimezone得到时区正确的OffsetDateTime,再加上JDBC规范的要求,OffsetDateTime还是首选。至于PostgreSQL的兼容性,可以在FreeMarker和Thymeleaf中自定义日期格式化方法。

Java是什么

Java是一门面向对象编程语言,可以编写桌面应用程序、Web应用程序、分布式系统和嵌入式系统应用程序。

看完上述内容,你们掌握Java 8日期与数据库日期的映射关系是什么的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注编程网行业资讯频道,感谢各位的阅读!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯