一、背景
数据库表中为了记录用户操作过程,大部分表都有创建用户、更新用户、创建时间、更新时间的公用参数,且为了逻辑删除加了delete_flag的删除标记,为了租户数据隔离增加了tenant_id的租户ID。如果每个表在插入数据之前都要去单独一个个属性去设置,代码就显得冗余繁杂,那有什么好的解决方案呢?
二、解决方案
1、切面编程,直接在mybatis插入之前拼接这几个字段的sql语句,这种方式在mabatis的xml文件中也不需要去写这几个字段的相关sql,当然也有缺点,如服务和服务接口内部调用可能没带token,取不到租户ID和用户ID时,切面方式可能会直接异常,这时还是需要走代码设置属性流程。在本篇文章不展开讲这种方式。
2、封装公用方法,利用反射机制设置公共参数,代码如下:
import org.springframework.stereotype.Repository;
import org.springframework.util.ReflectionUtils;
import top.rdfa.framework.auth.client.UnifyAuthContextHolder;
import top.rdfa.framework.auth.facade.entity.UserInfo;
import java.lang.reflect.Method;
import java.util.Date;
@Repository
public class InjectCommonParam {
/**
* 插入前触发,填充公用参数
* @param obj 待设置公共参数的对象
*/
public void insertFills(Object obj) {
//token中获取用户信息
UserInfo user = UnifyAuthContextHolder.getUserInfo();
if(user!=null){
setField(obj, "setCreateById", user.getUserId());
setField(obj, "setUpdateById", user.getUserId());
setField(obj, "setTenantId", user.getTenantId());
}
setField(obj, "setCreateTime", new Date());
setField(obj, "setUpdateTime", new Date());
setField(obj, "setDeleteFlag", 0);
}
/**
* @param obj 对象
* @param methodName 方法名
* @param value 待设置的值
*/
private void setField(Object obj, String methodName, Object value) {
Method method = ReflectionUtils.findMethod(obj.getClass(), methodName, value == null ? String.class : value.getClass());
if (method != null) {
ReflectionUtils.invokeMethod(method, obj, value);
}
}
}
调用方式,调用类中增加
@Resource private InjectCommonParam injectCommonParam;
用户对象入库前调用反射设置公共参数
injectCommonParam.insertFills(user);
角色对象入库前调用反射设置公共参数
injectCommonParam.insertFills(role);