关于mysql时间类型和java model的日期类型映射
文章目录
- 背景
- mysql
- TIMESTAMP
- DATETIME
- java model
- java.util.Date
- java.time.LocalDateTime
- 总结
- 一般情况下选择 DATETIME+LocalDateTime 组合
- mysql 版本过低时,mysql=>TIMESTAMP
- jdk 版本过低时,model=>Date
- mybatis 版本过低时,model=>Date
- 多个国家时间,BIGINT+Long
- 其他
背景
对于比如 create_time,update_time 这种时间类型,一般 mysql 中是存储什么类型,java model 中对应又应该设置什么类型呢?
虽然这是一个常见的问题,但是它却有着各种版本之间复杂的联系,到底选择什么类型,和各种版本,以及代码逻辑有着各种关系
你可能需要依靠这些信息综合判断应该选择什么类型
mysql
create_time,update_time 可以设置:
- TIMESTAMP 时间范围小
- DATETIME 时间范围大
TIMESTAMP
占用 4 字节
存储范围从 1970-01-01 00:00:01 UTC 到 2038-01-19 03:14:07 UTC,当真实日期超过 2038-01-19 03:14:07 UTC 时,TIMESTAMP 类型确实无法存储
会自动进行时区转换,当你向 TIMESTAMP 字段插入数据时,MySQL 会将客户端提供的时间按照当前会话的时区转换为 UTC 时间,再存储对应的秒数
支持 DEFAULT CURRENT_TIMESTAMP 和 ON UPDATE CURRENT_TIMESTAMP 特性,适合记录时间戳
不过,从 MySQL 8.0.19 版本开始,支持 TIMESTAMP(6) (最多 6 位小数秒,使用 8 字节存储,范围可达到 0000-01-01 00:00:00 到 9999-12-31 23:59:59
TIMESTAMP 存储的是从 Unix 纪元(即 1970 年 1 月 1 日 00:00:00 UTC)开始的秒数,这是因为 Unix 系统最初采用这种方式来记录时间
DATETIME
占用 8 字节
存储范围从 1000-01-01 00:00:00 到 9999-12-31 23:59:59
不进行时区转换
能更精确地存储日期和时间
在 MySQL 5.6.5 之前,DATETIME 不支持 DEFAULT CURRENT_TIMESTAMP 和 ON UPDATE CURRENT_TIMESTAMP。从 MySQL 5.6.5 版本开始,DATETIME 支持这些特性
java model
createTime,updateTime 可以设置:
- java.util.Date 传统时间范围,线程不安全
- java.time.LocalDateTime jdk 8 新引入的时间范围,线程安全
java.util.Date
传统的日期时间类型
在 Java 8 之前广泛使用
线程不安全
java.time.LocalDateTime
Java 8 引入的新日期时间 API
线程安全且功能更强大
使用该类型时,需要 MyBatis 版本支持,3.4.5 及以上
总结
一般情况下选择 DATETIME+LocalDateTime 组合
一般情况,你的 jdk 基本都是 >= 8,你的 mysql 一般也是 >= 5.7
因此一般情况建议是 mysql 选择 DATETIME,java model 选择 LocalDateTime
mysql 版本过低时,mysql=>TIMESTAMP
mysql 版本比如低于 5.6.5 时候,DATETIME 是不支持的 DEFAULT CURRENT_TIMESTAMP 和 ON UPDATE CURRENT_TIMESTAMP 特性的,这样自动的生成和更新创建时间和更新时间就会比较麻烦
因此可以使用 mysql 选择 TIMESTAMP
jdk 版本过低时,model=>Date
jdk 比如低于了 8,java model 中只能选择 Date 了
mybatis 版本过低时,model=>Date
比如低于 3.4.5,那么 java model 中只能选择 java.util.Date 了
多个国家时间,BIGINT+Long
如果要存储多个国家时间,想要保证 msyql 存储的时间是统一标准,就需要存储时间戳,因此需要使用 BIGINT 类型,那么 java model 对应使用 Long
其他
如果你的 mysql 版本 >= 8.0.19,TIMESTAMP 也支持 8 个字节,并且时间范围扩展到 0000-01-01 00:00:00 到 9999-12-31 23:59:59,那么 mysql 你选择 TIMESTAMP 或 DATETIME 都可
如果没有线程安全问题,完全串行,那么 java model 选择 Date 或 LocalDateTime 都可
如果你不是通过 mysql 数据库设置 DEFAULT CURRENT_TIMESTAMP 和 ON UPDATE CURRENT_TIMESTAMP 来让创建时间和更新时间自动生成,而是通过代码的方式来生成这些时间,那么 mysql 选择 TIMESTAMP 或 DATETIME 都可
如果你不介意时间范围太短,那么 TIMESTAMP 或 DATETIME