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";@Overridepublic 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);}}@Overridepublic 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";@Overridepublic 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);}}}@Overridepublic 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", "否");@EnumValueprivate final String code;private final String msg;Flag(String code, String msg) {this.code = code;this.msg = msg;}@Overridepublic String getCode() {return this.code;}@Overridepublic String getMsg() {return this.msg;}@Overridepublic 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 */
private 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);