首页
学习
活动
专区
圈层
工具
发布

SpringBoot 公共字段自动填充的6种神技,开发效率飙升!

前两天在公司茶水间碰到老李,他一边冲咖啡一边吐槽说“你知道不,我们那个小程序上线出Bug了,居然是因为没填createTime字段…我真是气得脑瓜仁疼”。我说你们不是用的 SpringBoot 吗?他翻了个白眼,“是啊,用的是啊,但谁让我们一直手动填这些字段的,哪个不长眼的漏了就出事”。我当时一边喝豆浆一边心想,哎呀你们这是不懂自动填充的六种玩法啊,得亏我上个月刚整理了一遍,不然我也得跟你一样天天焦头烂额。

第一种:最基础的 @TableField 自动填充

这个其实很多人知道但还是不用,可能就图省事。你只要在字段上加个注解@TableField(fill = FieldFill.INSERT),比如说createTime,然后再配置一个MetaObjectHandler的实现类,就能在 insert 的时候自动把当前时间戳塞进去。比如:

@TableField(fill = FieldFill.INSERT)

private LocalDateTime createTime;

然后你的MetaObjectHandler长这样:

@Override

public void insertFill(MetaObject metaObject) {

  this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());

}

就这点代码,省下的可能是几百次脑抽写错字段的机会。

第二种:同时搞定 insert 和 update 的 updatedTime

这个也特别常见,尤其是你那种表每次改都要记录updateTime的场景。我一般是这么写的:

@TableField(fill = FieldFill.INSERT_UPDATE)

private LocalDateTime updateTime;

MetaObjectHandler里就加一个updateFill:

@Override

public void updateFill(MetaObject metaObject) {

  this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());

}

我之前在电梯里还教过我们测试妹子怎么查更新记录,全靠这个。

第三种:用枚举搞定状态字段填充

这个之前被我们项目老大夸过“干得漂亮”,就是那种新建一条记录的时候,状态字段默认要是ENABLED,你就可以写成:

@TableField(fill = FieldFill.INSERT)

private StatusEnum status;

然后填充逻辑里:

this.strictInsertFill(metaObject, "status", StatusEnum.class, StatusEnum.ENABLED);

比你每次写entity.setStatus(StatusEnum.ENABLED)看起来就高级,而且更不容易出错。

第四种:ThreadLocal 方式搞当前登录人填充

这个就稍微复杂点,但是特别实用。像我之前做审批流系统的时候,每条记录要带上谁创建的、谁修改的。我们是这么搞的:

先用一个UserContextHolder去放 ThreadLocal:

public class UserContextHolder {

  private static final ThreadLocal<User> userThreadLocal = new ThreadLocal<>();

  public static void set(User user) { userThreadLocal.set(user); }

  public static User get() { return userThreadLocal.get(); }

  public static void clear() { userThreadLocal.remove(); }

}

然后在拦截器里塞进去用户信息,MetaObjectHandler 里面就可以这么写:

this.strictInsertFill(metaObject, "createdBy", String.class, UserContextHolder.get().getUsername());

你要是用了 Sa-Token 或者 Spring Security,改一下获取逻辑就完事。

第五种:通过拦截器统一处理,脱离 MyBatis-Plus 也能玩

有次我们组要迁一个老项目,那时候没用 MyBatis-Plus,我就手搓了个Interceptor,专门拦住 insert 和 update 的语句,把那些字段强行加上默认值。虽然不推荐这么搞,但在没有 MetaObjectHandler 的年代,这就是救命稻草。

public class FillFieldInterceptor implements Interceptor {

  // 简化版逻辑,实战中你得判断方法类型和目标字段

}

就像以前没空调的时候靠蒲扇过夏天,虽然土,但真管用。

第六种:数据库默认值兜底 + 显式字段忽略策略

这个真的是终极保险了,你不仅在 Java 层填了字段,数据库层也加上默认值,比如DEFAULT CURRENT_TIMESTAMP。再配合一下实体类字段写成:

@TableField(value = "create_time", fill = FieldFill.INSERT)

private LocalDateTime createTime;

而不是用transient或者@JsonIgnore这种让它不进数据库的,万一真漏了、或者有人手动写了个裸 SQL,不也还有数据库兜着吗?

说真的,每次看到别人还在手动塞createTime,我都想拍拍他肩膀说一句,“兄弟,春天早来了,你咋还自己种麦子呢”。这几个技巧放在一起用,开发体验真的舒服,字段那一坨烦人的屎山就瞬间少一半。

不过别光看,赶紧回去改你项目里的那些实体类吧,免得哪天改接口的时候又听到有人喊“卧槽,我忘填字段了”……

  • 发表于:
  • 原文链接https://page.om.qq.com/page/OWoi0KwUnnZPBFQKOil7VZiA0
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。
领券