为什么数据库设计中要使用long来替换Date类型

对数据库中的记录进行操作的时候,牵涉到对时间数据的处理,比如创建时间、修改时间等,一般使用 long 类型代替 DateTimestamp。比如 Mybatis 的池连接类 PooledConnection

1
2
3
private long checkoutTimestamp; // 检查时间戳
private long createdTimestamp; // 创建时间戳
private long lastUsedTimestamp; // 最后一次使用时间戳

MySQL、SQL Server中的表示时间的类型

Date——日期。格式:YYYY-MM-DD。占用三个字节。

Datetime——日期和时间的组合。格式:YYYY-MM-DD HH:MM:SS。1000-01-01 00:00:00 ~ 9999-12-31 23:59:59,占用8个字节。适合用来记录数据的原始的创建时间。

Timestamp——日期+时间,使用 Unix 纪元(‘1970-01-01 00:00:00’ UTC) 至今的描述来存储。格式:YYYY-MM-DD HH:MM:SS。占用4个字节,'1970-01-01 00:00:01' UTC ~ '2038-01-09 03:14:07' UTC,适合用来记录数据的最后修改时间,只要更改记录中其他字段的值,timestamp字段的值都会被自动更新。

bigint——表示从-2^63 (-9,223,372,036,854,775,808) 到 2^63-1 (9,223,372,036,854,775,807),占用8个字节。

Java 中表示时间的类型

Java 中对时间处理的类比较混乱,处理时间的类有:java.util.Datejava.sql.Datejava.sql.Timejava.sql.Timestampjava.util.Calendarjava.util.TimeZone。使用过程中存在以下问题:

  1. 获取当前时间时,各个地区在同一个时间点会有不同的时间表示。
  2. java.util.Date 转为 java.sql.Date 时候,日期的时分秒会被去掉,数据的精度发生了变化。而 JDBC 中定义接口时候,用的是 java.sql.Date,而我们常常用到的 Date 都是 java.util.Date,这往往导致一些转换过程中发生误差。
  3. java.sql.Date在JDBC接口中使用,如果对其进行修改,JDBC 接口规范也要改,那么将引发各个数据库厂商对数据库驱动也要改,这是不可接受的。
  4. java.sql.Timestamp 类,它保持了日期数据原有的精度。可以实现和 java.util.Date 的无损转换。但是 Timestamp 这个类在一些预定义SQL中常常会出问题。

解决办法

将 Date 类型转换为 long 类型。这样一来:

  1. 有利于计算时间差
  2. 方便 Java 与数据库之间的传输
  3. 通过 long now = System.currentTimeMillis() 获得当前时间的 long 类型 也可以通过 Date date1=new Date() 来获得当前时间,再用 long time = date.getTime() 将其转化为 long类型。然后在数据库中的相应字段设置类型为 bigint 即可,在数据库中取得数据后,可以在转为相应的时间格式。