背景:
当一个外部系统调用我们一个免登录的API接口,在我们数据库去保存或更新一条数据时,库表中的创建人和更新人字段不是正确的值。
但是代码层面我们是有正确的设置创建人和更新人,查询sql日志发现我们设置的值统一被替换为“admin”了。
这个时候才明白为什么另一个接口中在保存完数据后,还有一个单独更新创建人的更新操作。
但是这样也是有问题的。在更新操作的时候,创建人是可以被正确的修改,但是更新人还是会被替换为“admin”的。
找BUG
百度后发现应该是 MetaObjectHandler 类的对数据做出的更改。
MetaObjectHandler简介
MyBatis-Plus的MetaObjectHandler是一个拦截器,用于处理实体字段的自动填充。当我们使用MyBatis-Plus进行数据库操作时,有些字段的值是需要在插入或更新操作时动态生成的,比如创建时间、修改时间、创建者、修改者等等。这时我们就可以使用MetaObjectHandler拦截器来实现自动填充。
MetaObjectHandler拦截器主要提供以下两个方法:
- insertFill:用于插入操作时的字段填充;
- updateFill:用于更新操作时的字段填充。
这些方法会在执行插入或更新操作时自动调用,从而完成字段填充的功能。我们可以通过继承MetaObjectHandler类并重写这些方法来达到自定义填充的目的。需要注意的是,除了自动填充之外,MetaObjectHandler还可以实现一些其他的功能,比如逻辑删除等等。
然后在项目中找到如下代码:
@Configuration
public class MyBatisConfig implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
String userName = "admin";
try {
userName = SecurityUtils.getUsername();
} catch (Exception e) {
}
this.setFieldValByName("createBy", userName, metaObject);
this.setFieldValByName("updateBy", userName, metaObject);
this.setFieldValByName("createTime", new Date(), metaObject);
this.setFieldValByName("updateTime", new Date(), metaObject);
}
@Override
public void updateFill(MetaObject metaObject) {
String userName = "admin";
try {
userName = SecurityUtils.getUsername();
} catch (Exception e) {
}
this.setFieldValByName("updateBy", userName, metaObject);
this.setFieldValByName("updateTime", new Date(), metaObject);
}
}
查看代码可以发现,在外部系统免登录的情况下,createBy 字段和 updateBy 字段 都会默认填充为 “admin”;这就解释即使我们手动设置了这些值,在插入数据时还是被替换成“admin”了。
修复BUG
我们需要对上述代码做些优化:
@Configuration
public class MyBatisConfig implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
String userName = "admin";
try {
userName = SecurityUtils.getUsername();
} catch (Exception e) {
}
// createBy和updateBy字段为空时,才自动填充创建人和修改人的值
Object createBy = getFieldValByName("createBy", metaObject);
Object updateBy = getFieldValByName("updateBy", metaObject);
if (createBy == null) {
this.setFieldValByName("createBy", userName, metaObject);
}
if (updateBy == null) {
this.setFieldValByName("updateBy", userName, metaObject);
}
this.setFieldValByName("createTime", new Date(), metaObject);
this.setFieldValByName("updateTime", new Date(), metaObject);
}
@Override
public void updateFill(MetaObject metaObject) {
String userName = "admin";
try {
userName = SecurityUtils.getUsername();
} catch (Exception e) {
}
Object updateBy = getFieldValByName("updateBy", metaObject);
if (updateBy == null) {
this.setFieldValByName("updateBy", userName, metaObject);
}
this.setFieldValByName("updateTime", new Date(), metaObject);
}
}
至此问题成功被解决。
标签:userName,metaObject,admin,setFieldValByName,MetaObjectHandler,updateBy,MyBatisPl From: https://www.cnblogs.com/danielzzz/p/17434348.html