MyBatis-Plus 的自动填充 —— 值为null
MyBatis-Plus 的自动填充
MyBatis-Plus 提供的字段自动填充功能是一种非常实用的特性,它能够在插入或更新数据库记录时自动填充一些公共字段,如创建时间(createTime)、更新时间(updateTime)、创建人(createBy)、更新人(updateBy)等。这一功能极大地简化了开发过程,减少了重复的代码编写,提高了开发效率。
使用步骤:
-
在实体类中,使用
@TableField
注解,来标明哪些字段是需要自动填充的,并且需要指定填充策略@Data @NoArgsConstructor @AllArgsConstructor public class BaseEntity implements Serializable { /** 创建者 */ @ApiModelProperty(value = "创建者") @TableField(fill = FieldFill.INSERT) private String createBy; /** 创建时间 */ // ... /** 更新者 */ @ApiModelProperty(value = "更新者") @TableField(fill = FieldFill.UPDATE) private String updateBy; /** 更新时间 */ // ... }
-
新增 MyMetaObjectHandler 来处理字段自动填充
@Slf4j @Component public class MyMetaObjectHandler implements MetaObjectHandler { @Override public void insertFill(MetaObject metaObject) { log.info("开始插入填充..."); // ... 在插入时需要填充的字段 } @Override public void updateFill(MetaObject metaObject) { log.info("开始更新填充..."); this.strictInsertFill(metaObject, "updateTime", Date.class, DateUtils.getNowDate()); // ... 其它字段 } }
但是在这种填充情况下,可能会遇到一个问题,在使用 strictInsertFill()
方法在更新的时候对指定字段填充时,即使前端并没有传值,且后端正确执行了填充方法,但是参考控制台输出的 SQL 语句,提示该字段依旧为空,如:

在官网中可以看到这么一句话:MetaObjectHandler
提供的默认方法策略是:如果属性有值则不覆盖,如果填充值为 null
则不填充。
然而这句话与我们的实际情况截然相反 ,这是因为对于 strictInsertFill()
方法而言,strictInsertFill
方法的目的是在插入或更新操作时,只有当字段值为 null
时才进行填充。但是,如果 updateTime
字段被框架或数据库视为已经存在(即使值为 null
), strictInsertFill
将不会对其进行填充。
前端请求数据格式:
要解决这个问题,可以尝试以下几种方法:
-
使用
setFieldValByName
方法:如果你的目标是在更新操作时总是填充updateTime
字段,即使它当前为null
,你可以使用setFieldValByName
方法。这个方法会强制在更新操作时填充字段,只要字段存在。this.setFieldValByName("updateTime", DateUtils.getNowDate(), metaObject);
-
在前端传递的数据中,直接将要填充的字段清除,即不传递
updateTime
、updateBy
等数据。