1填充简介
在更新、和修改、删除的时候,我们经常要修改创建时间,更新时间,修改人等信息,每个方法上都写不会有问题,但是也可以全局配置,减少重复代码
1.1实现方法:这里
表设计:逻辑严谨的表设计,一般会有以下6个字段,在CRUD的时候做好维护
1.2给对应的字段添加上注解@TableField(fill = FieldFill.UPDATE)
@Data
@EqualsAndHashCode(callSuper = false)
public class User extends Model<User> {
/**
* 主键
*/
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
private Integer parentId;
@TableField(fill = FieldFill.INSERT)
private Date createTime;
@TableField(fill = FieldFill.INSERT)
private Integer createId;
@TableField(fill = FieldFill.INSERT)
private String createName;
@TableField(fill = FieldFill.UPDATE)
private Integer updateId;
@TableField(fill = FieldFill.UPDATE)
private Date updateTime;
@TableField(fill = FieldFill.INSERT)
private String updateName;
}
1.3常用的值有以下四种
public enum FieldFill {
/**
* 默认不处理
*/
DEFAULT,
/**
* 插入时填充字段
*/
INSERT,
/**
* 更新时填充字段
*/
UPDATE,
/**
* 插入和更新时填充字段
*/
INSERT_UPDATE
}
2配置类
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
@Autowired
private IUserService userService;
@Override
public void insertFill(MetaObject metaObject) {
Date date = new Date();
User currentUser = userService.getCurrentUser();
this.strictInsertFill(metaObject, "createTime", Date.class, date); // 起始版本 3.3.0(推荐使用)
this.strictInsertFill(metaObject, "createName", String.class, currentUser.getName()); // 起始版本 3.3.0(推荐使用)
this.strictInsertFill(metaObject, "createId", Integer.class, currentUser.getId()); // 起始版本 3.3.0(推荐使用)
// 或者
//this.strictUpdateFill(metaObject, "createTime", () -> date, Date.class); // 起始版本 3.3.3(推荐)
// 或者
//this.fillStrategy(metaObject, "createTime", date); // 也可以使用(3.3.0 该方法有bug)
}
@Override
public void updateFill(MetaObject metaObject) {
Date date = new Date();
User currentUser = userService.getCurrentUser();
this.strictUpdateFill(metaObject, "updateTime", Date.class, date); // 起始版本 3.3.0(推荐)
this.strictUpdateFill(metaObject, "updateId", Integer.class, currentUser.getId()); // 起始版本 3.3.0(推荐)
this.strictUpdateFill(metaObject, "updateName", String.class, currentUser.getName()); // 起始版本 3.3.0(推荐)
// 或者
//this.strictUpdateFill(metaObject, "updateTime", () -> date, Date.class); // 起始版本 3.3.3(推荐)
// 或者
//this.fillStrategy(metaObject, "updateTime", date); // 也可以使用(3.3.0 该方法有bug)
}
}
3测试代码
@Test
public void update() {
LambdaUpdateWrapper<User> userQueryWrapper = Wrappers.<User>lambdaUpdate()
.eq(User::getName, "梅长苏")
.eq(User::getAge,30);
User user = new User();
user.setEmail("123456@qq.com");
userMapper.update(user,userQueryWrapper);
}
打印sql
==> Preparing: UPDATE user SET email=?, update_id=?, update_time=?, update_name=? WHERE is_delete=0 AND (name = ? AND age = ?)
==> Parameters: 123456@qq.com(String), 1(Integer), 2021-01-19 13:43:56.972(Timestamp), 梅长苏(String), 梅长苏(String), 30(Integer)
<== Updates: 1
4可能出现的问题
4.1导致自动填充失效
1、配置类未加上@component
2、实体字段未加上@TableField(fill = FieldFill.UPDATE)注解
3、使用实体为空的更新方式,如下,修改为updateById或者像测试代码那样就行
//这是无效的示例
@Test
public void update() {
LambdaUpdateWrapper<User> userQueryWrapper = Wrappers.<User>lambdaUpdate()
.eq(User::getName, "梅长苏")
.eq(User::getAge,30)
.set(User::getEmail,"123@qq.com");
userMapper.update(null,userQueryWrapper);
}
4.2插入数据可能会乱码的结局
数据库配置加上characterEncoding=UTF8
datasource:
url: jdbc:mysql://127.0.0.1:3306/testplus?serverTimezone=Hongkong&useUnicode=true&characterEncoding=UTF8&useSSL=false&allowPublicKeyRetrieval=true
driver-class-name: com.mysql.cj.jdbc.Driver
username: xxx
password: xxx
5自动填充优化
5.1因为有些表可能没有createTime、updateTime的等字段
所以需要做一个实体是否有字段的判断,修改配置类MyMetaObjectHandler
@Override
public void insertFill(MetaObject metaObject) {
Date date = new Date();
User currentUser = userService.getCurrentUser();
boolean createTime = metaObject.hasSetter("createTime");
if(createTime){
this.strictInsertFill(metaObject, "createTime", Date.class, date); // 起始版本 3.3.0(推荐使用)
}
}
5.2自己在sql中设置了值,就不填充,自己没设置就填充
@Override
public void updateFill(MetaObject metaObject) {
Date date = new Date();
User currentUser = userService.getCurrentUser();
Object updateTime = getFieldValByName("updateTime", metaObject);
if(updateTime == null){
this.strictUpdateFill(metaObject, "updateTime", Date.class, date); // 起始版本 3.3.0(推荐)
}
}