Java 8 Time API结合Hibernate实现MySQL毫秒级时间存储
解决MySQL存储LocalDateTime丢失毫秒/纳秒精度的问题
这个问题我之前在项目里也踩过坑,本质是数据库字段类型、Hibernate映射和JDBC驱动的配合没到位,咱们一步步来搞定:
1. 先修正MySQL的字段类型
MySQL默认的DATETIME类型只保留到秒级,这就是你看到2018-05-12 22:24:31这种无毫秒格式的原因。要支持毫秒甚至更高精度,需要给字段指定精度:
- 要存储毫秒级精度,把字段改成
DATETIME(3) - 要存储微秒级精度(MySQL最高支持到微秒,LocalDateTime的纳秒会被自动截断到微秒,完全满足你至少毫秒级的需求),改成
DATETIME(6)
执行对应的SQL修改语句:
ALTER TABLE event MODIFY COLUMN time DATETIME(3) NOT NULL;
2. 优化实体类的注解配置
虽然你引入了hibernate-java8依赖来支持Java 8时间类型,但最好显式指定字段定义,避免Hibernate自动生成不符合预期的字段类型:
@Entity @Table(name = "event") public class Event { @Id @GeneratedValue @Column(name = "id") private long id; // 显式指定字段类型为带精度的DATETIME @Column(name = "time", columnDefinition = "DATETIME(3)") private LocalDateTime time; // getter、setter等省略 }
3. 确保JDBC驱动版本达标
旧版本的MySQL JDBC驱动(比如mysql-connector-java 5.1.36及以下)不支持传递毫秒/微秒精度的时间到数据库,所以要把驱动版本升级到5.1.37及以上,或者直接用最新的8.x版本:
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.33</version> </dependency>
补充说明
- 你提到
Timestamp和Date无法存储纳秒,这点完全正确,但我们不需要依赖它们——直接用Java 8的LocalDateTime搭配MySQL带精度的DATETIME类型,就能完美实现至少毫秒级的存储。 - MySQL的
TIMESTAMP类型也支持指定精度(比如TIMESTAMP(3)),但它的时间范围比DATETIME小(只能到2038年),如果你的业务时间范围不受限,优先用DATETIME。
内容的提问来源于stack exchange,提问作者Glains
相关产品推荐
相关产品推荐

