如何在JPA审计中以毫秒数存储时间戳?附数据库时间格式建议
用毫秒数存储审计时间戳 + 数据库日期/时间戳处理推荐
一、修改审计类为毫秒数存储
如果你想直接用System.currentTimeMillis()的返回值(毫秒数)存储时间戳,可以通过JPA的生命周期回调注解手动赋值,替代原来的Spring Data Auditing自动注入方式,代码修改如下:
@MappedSuperclass public abstract class Auditable { @Column(name = "crt_date", columnDefinition = "BIGINT") private long createdDate; @Column(name = "upd_date", columnDefinition = "BIGINT") private long updatedDate; // 实体创建时自动设置创建和更新时间 @PrePersist protected void onCreate() { long now = System.currentTimeMillis(); createdDate = now; updatedDate = now; } // 实体更新时自动刷新更新时间 @PreUpdate protected void onUpdate() { updatedDate = System.currentTimeMillis(); } // Getters and Setters public long getCreatedDate() { return createdDate; } public void setCreatedDate(long createdDate) { this.createdDate = createdDate; } public long getUpdatedDate() { return updatedDate; } public void setUpdatedDate(long updatedDate) { this.updatedDate = updatedDate; } }
修改说明:
- 将原
Date类型字段改为long,对应数据库BIGINT类型(足够存储毫秒数); - 移除
@CreatedDate、@LastModifiedDate和@EntityListeners(AuditingEntityListener.class),改用@PrePersist和@PreUpdate回调直接调用System.currentTimeMillis()赋值,完全匹配你的需求; - 无需额外配置Spring Data Auditing,逻辑直观可控。
二、数据库时间戳/日期的推荐格式
根据业务场景不同,推荐两种主流格式:
1. 数据库原生日期时间类型(优先推荐)
- 数据库类型:MySQL用
TIMESTAMP(带时区)或DATETIME(不带时区),PostgreSQL用TIMESTAMP WITH TIME ZONE; - 对应Java类型:JDK8+推荐用
java.time.LocalDateTime/java.time.ZonedDateTime(线程安全,API更友好),旧版本可用java.util.Date; - 适用场景:大多数业务系统,需要频繁进行日期范围查询、报表统计、时区转换的场景;
- 优点:可读性强,支持数据库原生日期函数(如
DATE_ADD、WHERE crt_date BETWEEN ? AND ?),无需手动处理时区转换。
2. 毫秒级时间戳(BIGINT类型)
- 数据库类型:
BIGINT; - 对应Java类型:
long; - 适用场景:分布式系统、对性能要求极高、或需要避免时区问题的场景;
- 优点:存储体积小(仅8字节),序列化/传输效率高,纯数值无时区依赖;
- 缺点:可读性差,数据库层面无法直接用日期函数,需转换为日期类型才能进行日期相关操作。
不推荐格式:字符串存储日期
不要用VARCHAR存储日期字符串,会导致查询效率极低、格式易混乱、时区处理复杂等问题。
内容的提问来源于stack exchange,提问作者spyder
相关产品推荐
相关产品推荐

