别再手动 set 时间了,JPA 一行注解全帮你搞定!

82 阅读5分钟



大家好,我是小米,一个写代码也写故事的31岁程序员。

上周五晚上,我在工位上加班修 Bug,手里那杯咖啡都凉透了。原因嘛——老板的一句话:“小米,你这表记录谁创建的、什么时候改的,怎么都没写?”我一脸懵:“啊?这不是数据库自带的吗?”老板笑了笑,“你去查查 JPA Audit。”

就这样,我打开电脑,走上了一条“审计字段自动填充”的觉醒之路。

那些年我们手动维护的时间戳

还记得刚入行那会儿,我写的每个实体类都像这样:

每次插入数据,我要在 Service 里手动加:

每次修改,又要写:

那时候觉得很自然,但后来项目一多,几十个表、几百个接口,这种重复代码简直要命。更惨的是——忘了写!测试一改表数据,时间没更新,历史数据都乱套。于是我暗暗发誓:“有朝一日,一定要让这些字段自动更新!”

直到那天,JPA 的 @CreatedDate 和 @LastModifiedDate 出现在我的视野中,像是照进加班狗世界的一束光。

JPA Audit:让时间自动生长的魔法

Spring Data JPA 提供了一个非常优雅的方案:Auditing(审计)机制。简单来说,就是自动帮你记录实体的创建时间、修改时间、创建人、修改人。

其中,最常用的两个注解就是:

  • @CreatedDate —— 自动记录创建时间。
  • @LastModifiedDate —— 自动记录最后修改时间。

是不是一看名字就懂了?没错,真正的懒人神器。

动手开整:三步启用审计魔法

第一步:在配置类上开启审计功能

在任意一个配置类或启动类上加上这行注解:

@EnableJpaAuditing

这句话的意思很简单:告诉 Spring,“以后帮我盯着数据库记录的变化,谁新建、谁修改都记下来!”

第二步:在实体类上声明审计监听

在你的实体类上加个监听器,让 Spring 知道要“监听”它的变化。

@EntityListeners(AuditingEntityListener.class)

这一步很关键,没有它,Spring 不知道你要被审计。

第三步:加上注解就完事了

然后呢?没了。真的没了!你再执行一次插入或更新,时间就会自动写入数据库,不用再管!

原理浅析:Spring 到底干了啥?

有些同学可能会好奇:“小米,它到底是怎么知道我在新增还是修改呢?”

其实,Auditing 的底层机制是基于 实体监听器(Entity Listener) 的。

当你在实体上加上 @EntityListeners(AuditingEntityListener.class) 时,Spring 会在执行 save() 前后拦截生命周期事件(比如 @PrePersist、@PreUpdate),在插入前自动设置 @CreatedDate 字段,在更新前自动更新 @LastModifiedDate 字段。

这就像数据库触发器一样,但实现更轻量、更优雅,还能配合 @CreatedBy、@LastModifiedBy 记录操作人。

实战演练:一个例子走天下

我当时在项目里这样写的:

然后我在启动类上加上:

当我执行:

数据库里自动生成了时间戳!

过几分钟,我再修改这个用户名字,再执行一次 save,发现 update_time 自动变成最新的时间,而 create_time 完好无损。那一刻我真心感叹:Spring Data JPA 太懂程序员了!

顺便说下时间精度的小坑

很多人第一次用时会踩一个坑:数据库时间没自动更新。

别慌,常见原因就两个:

  1. 没加 @EnableJpaAuditing: 这是整个机制的总开关,不加它所有注解都白搭。
  2. 字段类型不对: 推荐用 LocalDateTime,如果你用 Date 或 Instant,要确保配置了合适的转换器。

另外,@Column(updatable = false) 千万别乱加在 @LastModifiedDate 上,否则它更新不了!

进阶玩法:记录创建人和修改人

除了时间,JPA 还能帮你自动记录“谁”创建了这条数据。

新增两个注解即可:

  • @CreatedBy
  • @LastModifiedBy

比如:

但要注意:这两个字段依赖于 AuditorAware 接口,你需要自己告诉 JPA 当前是谁在操作:

在真实项目中,你可以从登录上下文中取当前用户名。这样,每次插入或更新数据,createUser 和 updateUser 就会自动带上值。

再说点小故事

我把这套审计机制加到项目后,老板第一次审查代码时问:“你这次写的日志表不错啊,时间记录得很清楚。”

我笑着回:“我没写,Spring 帮我写的。”

他愣了两秒,然后竖起大拇指:“干得漂亮。”

从那以后,我再也不用担心忘记更新时间、创建时间。甚至在代码评审时,同事看到注解风格的审计方案,都感叹一句:“这才是优雅的后端。”

总结:三行注解,让代码更干净

用一句话总结今天的主角:

@CreatedDate 和 @LastModifiedDate,不仅让你少写代码,还能让系统更可靠、更可追溯。

它们背后体现的是“让框架帮你做重复的事,让开发者专注在业务逻辑”的理念。

所以,下一次当你新建实体类时,不妨给它加上这些注解。让时间自动生长,让代码更有生命力。

END

我是小米,一个喜欢分享技术的31岁程序员。如果你喜欢我的文章,欢迎关注我的微信公众号“软件求生”,获取更多技术干货!

我们下次见~