一、填充字段处理
需求描述:在插入数据的时候自动填充createTime和updateTime为当前插入数据的时间,在数据更新的时候修改updateTime为修改数据的时间。不需要人为的手动赋值。
- 创建数据库表,
表中有2个日期类型的字段 create_tme 和 update_time,默认值是 NULLCREATE TABLE `user` ( `id` bigint(20) NOT NULL COMMENT '主键ID', `name` varchar(30) DEFAULT NULL COMMENT '姓名', `age` int(11) DEFAULT NULL COMMENT '年龄', `email` varchar(50) DEFAULT NULL COMMENT '邮箱', `deleted` tinyint(4) DEFAULT NULL COMMENT '删除标识', `create_time` datetime DEFAULT NULL COMMENT '创建时间', `update_time` datetime DEFAULT NULL COMMENT '更新时间', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-
创建实体类 User.java,使用@TableField注解标记实体类中的哪些字段需要填充:
@Data public class User { private Long id; private String name; private Integer age; private String email; @TableField(fill = FieldFill.INSERT) private LocalDateTime createTime; @TableField(fill = FieldFill.INSERT_UPDATE) private LocalDateTime updateTime; }
FieldFill是一个枚举,用于指定在何种情况下会自动填充,有如下几种可选值:
-
DEFAULT:默认不处理
-
INSERT:插入时自动填充字段
-
UPDATE:更新时自动填充字
-
INSERT_UPDATE:插入和更新时自动填充字段
-
编写Mapper类 UserMapper.java
public interface UserMapper extends BaseMapper<User> { }
二、自定义填充默认数值
编写公共字段填充处理器类,该类继承了MetaObjectHandler类,重写 insertFill 和 updateFill 方法,在这两个方法中获取需要填充的字段以及默认填充的值。
- 填充处理器 MyMetaObjectHandler 在 Spring Boot 中需要声明 @Component 或 @Bean 注入
- strictInsertFill 和 strictUpdateFill 方法第二个参数写的是实体类里的属性名,不是对应数据库字段名。
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());
this.strictInsertFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
}
@Override
public void updateFill(MetaObject metaObject) {
this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
}
}
如果是3.3.0后面的版本,比如3.3.1.8,也可以改用下面更简单的写法(3.3.0不要用该方法,有bug)
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
this.fillStrategy(metaObject, "createTime", LocalDateTime.now());
this.fillStrategy(metaObject, "updateTime", LocalDateTime.now());
}
@Override
public void updateFill(MetaObject metaObject) {
this.fillStrategy(metaObject, "updateTime", LocalDateTime.now());
}
}
在一些比较旧的版本,为填充字段设置值的API如下,3.3.0之后已经不建议使用
this.setFieldValByName("createTime",LocalDateTime.now(),metaObject);
this.setFieldValByName("updateTime",LocalDateTime.now(),metaObject);
三、开始测试
- 插入一条数据,注意没有为 createTime 和 updateTime 赋值
@Test public void testInsert() { User user = new User(); user.setName("张三"); user.setAge(18); userMapper.insert(user); }
运行结果,createTime 和 updateTime 已经自动填充
- 根据 Id 更新一条数据,注意没有为 updateTime 赋值
@Test public void testUpdate() { User user = new User(); user.setId(1470933332267872258L); user.setName("张三张三"); user.setAge(20); userMapper.updateById(user); }
运行的结果:updateTime 在执行数据记录修改操作时被自动赋值