MyBatis-Plus 的自动填充 —— 值为null

MyBatis-Plus 的自动填充

MyBatis-Plus 提供的字段自动填充功能是一种非常实用的特性,它能够在插入或更新数据库记录时自动填充一些公共字段,如创建时间(createTime)、更新时间(updateTime)、创建人(createBy)、更新人(updateBy)等。这一功能极大地简化了开发过程,减少了重复的代码编写,提高了开发效率。

使用步骤:

  1. 在实体类中,使用 @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;
    
    	/** 更新时间 */
    	// ...
    }
    
    
  2. 新增 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 则不填充

自动填充字段 | MyBatis-Plus

然而这句话与我们的实际情况截然相反 ,这是因为对于 strictInsertFill() 方法而言,strictInsertFill 方法的目的是在插入或更新操作时,只有当字段值为 null 时才进行填充。但是,如果 updateTime 字段被框架或数据库视为已经存在(即使值为 null), strictInsertFill 将不会对其进行填充。

前端请求数据格式:

要解决这个问题,可以尝试以下几种方法:

  1. 使用 setFieldValByName 方法:如果你的目标是在更新操作时总是填充 updateTime 字段,即使它当前为 null,你可以使用 setFieldValByName 方法。这个方法会强制在更新操作时填充字段,只要字段存在。

    this.setFieldValByName("updateTime", DateUtils.getNowDate(), metaObject);
    
  2. 在前端传递的数据中,直接将要填充的字段清除,即不传递 updateTimeupdateBy 等数据。

posted @ 2025-02-23 11:11  大一点的小孩  阅读(90)  评论(0)    收藏  举报