字段自动填充(Mybatis-Plus)

对于表中日期类的属性我们想要系统自动来完成创建和更新,但并非所有数据库都支持,而且也不建议通过修改数据库来实现这一功能,好消息是Mybatis-Plus也拥有自动填充的功能,坏消息是好像有点小问题。

官方教程

官方的做法是在需要自动填充的字段上加上@TableField(fill = FieldFill.INSERT)注解,然后再自定义一个实现MetaObjectHandler结构的实现类且注册为Bean

注解用法

1
2
3
4
5
6
7
8
9
10
11
12
13
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
@TableId(type = IdType.AUTO)
private Integer id;
private String name;
private String password;
@TableField(fill = FieldFill.INSERT)
private Date createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
}

字段填充策略枚举类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public enum FieldFill {
/**
* 默认不处理
*/
DEFAULT,
/**
* 插入时填充字段
*/
INSERT,
/**
* 更新时填充字段
*/
UPDATE,
/**
* 插入和更新时填充字段
*/
INSERT_UPDATE
}

自定义实现类MyMetaObjectHandler

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
/*插入时的填充策略*/
@Override
public void insertFill(MetaObject metaObject) {
log.info("start insert fill ....");
this.strictInsertFill(metaObject, "createTime", Date::new, Date.class);
}

/*更新时的填充策略*/
@Override
public void updateFill(MetaObject metaObject) {
log.info("start update fill ....");
this.strictUpdateFill(metaObject, "updateTime", Date::new, Date.class);
}
}

然而执行插入操作后却仅带有FieldFill.INSERT的字段createTime被更新了,而带有FieldFill.INSERT_UPDATE的字段updateTime却没有更新,很奇怪

1
2
3
==>  Preparing: INSERT INTO user ( name, password, create_time, update_time ) VALUES ( ?, ?, ?, ? )
==> Parameters: dd(String), 123456(String), 2021-08-05 13:15:23.961(Timestamp), null
<== Updates: 1

解决方案

既然FieldFill.INSERT_UPDATE无效,那就在insertFill方法中再添加一条strictUpdateFill语句,这样每次插入新数据时,createTimeupdateTime都将会自动创建

所以FieldFill.INSERT_UPDATE到底有什么用,仅仅是用来看的吗

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
/*插入时的填充策略*/
@Override
public void insertFill(MetaObject metaObject) {
log.info("start insert fill ....");
this.strictInsertFill(metaObject, "createTime", Date::new, Date.class);
this.strictUpdateFill(metaObject, "updateTime", Date::new, Date.class);
}

/*更新时的填充策略*/
@Override
public void updateFill(MetaObject metaObject) {
log.info("start update fill ....");
this.strictUpdateFill(metaObject, "updateTime", Date::new, Date.class);
}
}