MetaObjectHandler:mybatistPlus提供给我们的一个拓展接口,我们可以重写 insertFill updateFill 方法来对我们入库的对象的字段进行设置,比如createTime,createBy,lockVersion等这些通用字段,这些字段基本每个表都会有,每次调用新增或者修改等需要入库的方法前去设置太过于麻烦,因此在这里进行设置!
当然也可以自己封装一个方法在插入前进行设置!但是每次插入也需要调用方法,这个接口还是省去了些力气,但是本次业务开发过程中就遇到这样的问题:
当我开启异步调用的时候,进行入库操作,SessionUser sessionUser = SessionTools.tokenInfo();就发生了错误!这个是获取当前登录用户信息的方法,其中调用了Sa-Token的接口
package com.jm.component;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.jm.base.dto.SessionUser;
import com.jm.base.util.SessionTools;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
/**
* mybatis持久化对象处理器
*
* @author zwf
* @date 2022/11/02
*/
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
private static final String CREATE_BY = "createBy";
private static final String CREATE_TIME = "createTime";
private static final String UPDATE_BY = "updateBy";
private static final String UPDATE_TIME = "updateTime";
private static final String LOCK_VERSION = "lockVersion";
@Override
public void insertFill(MetaObject metaObject) {
SessionUser sessionUser = SessionTools.tokenInfo();
LocalDateTime now = LocalDateTime.now();
if (metaObject.hasSetter(CREATE_BY) && metaObject.getValue(CREATE_BY) == null) {
metaObject.setValue(CREATE_BY, sessionUser.getUser().getId());
}
if (metaObject.hasSetter(CREATE_TIME)) {
metaObject.setValue(CREATE_TIME, now);
}
if (metaObject.hasSetter(UPDATE_BY) && metaObject.getValue(UPDATE_BY) == null) {
metaObject.setValue(UPDATE_BY, sessionUser.getUser().getId());
}
if (metaObject.hasSetter(UPDATE_TIME)) {
metaObject.setValue(UPDATE_TIME, now);
}
if (metaObject.hasSetter(LOCK_VERSION)) {
metaObject.setValue(LOCK_VERSION, 0);
}
}
@Override
public void updateFill(MetaObject metaObject) {
SessionUser sessionUser = SessionTools.tokenInfo();
if (metaObject.hasSetter(UPDATE_BY)) {
metaObject.setValue(UPDATE_BY, sessionUser.getUser().getId());
}
if (metaObject.hasSetter(UPDATE_TIME)) {
metaObject.setValue(UPDATE_TIME, LocalDateTime.now());
}
}
}
思路:异步调用的入库操作不使用MetaObjectHandler来设置这些字段,再调用入库前手动设置!但是只要是入库操作都会走这个类,所以我加了相关判断!
package com.jm.component;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.jm.base.dto.SessionUser;
import com.jm.base.option.meta.Flag;
import com.jm.base.util.SessionTools;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
/**
* mybatis持久化对象处理器
*
* @author zwf
* @date 2022/11/02
*/
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
private static final String CREATE_BY = "createBy";
private static final String CREATE_TIME = "createTime";
private static final String UPDATE_BY = "updateBy";
private static final String UPDATE_TIME = "updateTime";
private static final String LOCK_VERSION = "lockVersion";
private static final String IS_ASYNC_FLAG = "isAsyncFlag";
@Override
public void insertFill(MetaObject metaObject) {
Flag flag = Flag.F;
if(metaObject.hasSetter(IS_ASYNC_FLAG)){
flag = (Flag) metaObject.getValue(IS_ASYNC_FLAG);
}
if(null != flag && Flag.F.equalCode(flag.getCode())){
SessionUser sessionUser = SessionTools.tokenInfoNotNull();
LocalDateTime now = LocalDateTime.now();
if (metaObject.hasSetter(CREATE_BY) && metaObject.getValue(CREATE_BY) == null) {
metaObject.setValue(CREATE_BY, sessionUser.getUser().getId());
}
if (metaObject.hasSetter(CREATE_TIME)) {
metaObject.setValue(CREATE_TIME, now);
}
if (metaObject.hasSetter(UPDATE_BY) && metaObject.getValue(UPDATE_BY) == null) {
metaObject.setValue(UPDATE_BY, sessionUser.getUser().getId());
}
if (metaObject.hasSetter(UPDATE_TIME)) {
metaObject.setValue(UPDATE_TIME, now);
}
if (metaObject.hasSetter(LOCK_VERSION)) {
metaObject.setValue(LOCK_VERSION, 0);
}
}
}
@Override
public void updateFill(MetaObject metaObject) {
Flag flag = Flag.F;
if(metaObject.hasSetter(IS_ASYNC_FLAG)){
flag = (Flag) metaObject.getValue(IS_ASYNC_FLAG);
}
if(null != flag && Flag.F.equalCode(flag.getCode())){
SessionUser sessionUser = SessionTools.tokenInfoNotNull();
if (metaObject.hasSetter(UPDATE_BY)) {
metaObject.setValue(UPDATE_BY, sessionUser.getUser().getId());
}
if (metaObject.hasSetter(UPDATE_TIME)) {
metaObject.setValue(UPDATE_TIME, LocalDateTime.now());
}
}
}
}
package com.jm.base.option.meta;
import com.baomidou.mybatisplus.annotation.EnumValue;
import com.jm.base.option.KV;
/**
* @author zwf
* @date 2022/10/13
*/
public enum Flag implements KV {
/**
* 是否标记
*/
T("1", "是"),
F("0", "否");
@EnumValue
private final String code;
private final String msg;
Flag(String code, String msg) {
this.code = code;
this.msg = msg;
}
@Override
public String getCode() {
return this.code;
}
@Override
public String getMsg() {
return this.msg;
}
@Override
public String getEnumName() {
return null;
}
}
1、我再会进行异步入库的对象新加了属性isAsyncFlag ,当代码走到MyMetaObjectHandler类中时,判断这个对象是否具备该字段,如果有则不需要该类处理createBy这些字段,就不会调用到Sa-Token的API。
2、入库前设置相关属性:
/**
* 异步开启之前调用satoken的API获取用户信息然后作为参数进入异步
*
* @param param 业务参数
* @param user 当前登录用户信息
*/
asynManager.doQueryMsg(param, SessionTools.tokenInfo().getUser());
/**
* 为异步新增的对象设置当前用户信息,异步操作标记:解决异步无法获取saToken信息问题
*
* @param t 需要设置的对象
* @param id 当前用户id
* @param time 当前时间
* @param <T>
*/
private <T extends MetaEntity> void setUserInfoAndFlag(T t, Long id, LocalDateTime time){
t.setCreateBy(id);
t.setCreateTime(time);
t.setUpdateBy(id);
t.setUpdateTime(time);
ReflectTools.setFieldValue(t, "isAsyncFlag", Flag.T);
}
// 使用
setUserInfoAndFlag(teacher, user.getId(), LocalDateTime.now());
teacherMapper.updateById(teacher);