2

Mybatis plus通用字段自动填充的最佳实践总结

 3 years ago
source link: https://segmentfault.com/a/1190000039103169
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

在进行持久层数据维护(新增或修改)的时候,我们通常需要记录一些非业务字段,比如:create_time、update_time、update_by、create_by等用来维护数据记录的创建时间、修改时间、修改人、创建人等信息。通常情况下我们需要对这些字段进行手动赋值。赋值的过程也比较冗余,都是重复操作。

  • 通常是为create_time赋值为系统的当前时间、update_time赋值为系统修改操作执行时的当前时间。
  • create_by(创建人)、update_by(修改人)赋值为当前的登录用户的用户名
xxxYyyZzz.setUpdateBy("zimug");    //数据记录更新操作人
xxxYyyZzz.setUpdateTime(new Date());   //数据记录更新操作的时间

Mybatis plus 为我们提供了一种一劳永逸的自动化赋值方式。

一、调整数据库表结构

以mysql数据库环境下的xxx_yyy_zzz表为例,在原有的表字段的基础上,添加下面的四个通用数据维护字段。

ALTER TABLE `xxx_yyy_zzz` ADD COLUMN `create_by` VARCHAR(64) NOT NULL COMMENT '本条记录创建人';
ALTER TABLE `xxx_yyy_zzz` ADD COLUMN `create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '本条记录创建时间';
ALTER TABLE `xxx_yyy_zzz` ADD COLUMN `update_by` VARCHAR(64) NOT NULL COMMENT '本条记录修改人';
ALTER TABLE `xxx_yyy_zzz` ADD COLUMN `update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '本条记录的修改时间';

二、通用维护信息父类-自动赋值的字段

既然我们对某一张表的数据进行新增创建、修改信息的维护,我们的实体类也要做必要的调整。为了避免为每一个实体类都加上这四个成员变量,我们定义一个父类BaseColumns。

@Data
public class BaseColumns {

  /**
   * 本条记录创建人,insert操作的时候自动为该字段赋值
   */
  @TableField(fill = FieldFill.INSERT 
  private String createBy;

  /**
   * 本条记录创建时间,insert操作的时候自动为该字段赋值
   */
  @TableField(fill = FieldFill.INSERT)
  private LocalDateTime  createTime;

  /**
   * 本条记录更新人,insert或update操作的时候自动为该字段赋值,select = false
   */
  @TableField(fill = FieldFill.INSERT_UPDATE,select = false)  
  private String updateBy;

  /**
   * 本条记录更新时间,insert或update操作的时候自动为该字段赋值,select = false
   */
  @TableField(fill = FieldFill.INSERT_UPDATE,select = false)
  private LocalDateTime updateTime;


}
  • fill = FieldFill.INSERT表示insert操作的时候自动为该字段赋值
  • fill = FieldFill.INSERT_UPDATE表示nsert或update操作的时候自动为该字段赋值
  • select = false表示在使用Mybatis Wrapper条件构造器进行查询的时候,不查询这个属性对应的数据库字段。数据修改时间操作人通常对于运维更有意义,所以通常不需要展示在web页面上,所以通常select查询的时候不包含它。(这个内容与我们本机的字段自动填充没有太直接的联系,但是在实际应用中是有意义的)

三、实体类的实现

下文实体类XxxYyyZzz对应数据库中的xxx_yyy_zzz表,除了以上四个通用字段,xxx_yyy_zzz表还包含其他的业务字段。

@Data
@EqualsAndHashCode(callSuper = true)
public class XxxYyyZzz extends BaseColumns {

    //其他的属性字段
}

四、自动赋值的规则

@Component
public class MybastisColumnsHandler implements MetaObjectHandler {

    @Resource
    private JwtTokenUtil jwtTokenUtil;  //我的工具类,用于从Token令牌中获取登陆人信息

    //设置数据新增时候的,字段自动赋值规则
    @Override
    public void insertFill(MetaObject metaObject) {
      this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());
      this.strictInsertFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());

      this.strictInsertFill(metaObject, "createBy", String.class, jwtTokenUtil.getUsernameFromToken());
      this.strictUpdateFill(metaObject, "updateBy", String.class, jwtTokenUtil.getUsernameFromToken());
    }

    //设置数据修改update时候的,字段自动赋值规则
    @Override
    public void updateFill(MetaObject metaObject) {
      this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
      this.strictUpdateFill(metaObject, "updateBy", String.class, jwtTokenUtil.getUsernameFromToken());
    }
}
  • 在数据新增的时候,自动为createTime、updateTime、createBy、updateBy赋值,即数据初始化。
  • 在数据修改的时候,自动为updateTime、updateBy赋值。
  • JwtTokenUtil是我写的一个工具类,从当前的登录用户JWT Token中获取当前登录用户的用户名。(你的系统里面获取当前登录用户名方法和我的不一样,但总之可以获取到)

五、实现效果

比如在进行数据更新的时候,下面的这两行代码就不需要写了,由 updateFill(MetaObject metaObject) 自动完成

//xxxYyyZzz.setUpdateBy("zimug");    //数据记录更新操作人
//xxxYyyZzz.setUpdateTime(new Date());   //数据记录更新操作的时间

xxxYyyZzzMapper.updateById(xxxYyyZzz);

同理,在数据insert操作的时候, insertFill(MetaObject metaObject) 将被自动执行。

欢迎关注我的博客,里面有很多精品合集

本文转载注明出处(必须带连接,不能只转文字): 字母哥博客 - zimug.com

觉得对您有帮助的话,帮我点赞、分享!您的支持是我不竭的创作动力!。另外,笔者最近一段时间输出了如下的精品内容,期待您的关注。


Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK