Mybatis拦截器实用案例-自动更新创建人,更新人信息

场景:

     项目里面有很多更新创建人,更新人的地方。每次新增,更新数据的时候都需要带入这些信息。

一般的处理逻辑:

     每个sql语句都携带创建人,更新人信息,人员信息从线程本地变量中获取。     

public class UserInfoThreadLocal{

    private static ThreadLocal<Long> userIdLocal = new ThreadLocal<>();

    
    public static Long getUserId(){
        
      return userIdLocal.get();

   }
    
}
每个业务sql都如下
insert into 表名(id,create_by) values(1,"张三")
更新时
update 表名 set 字段名 = #{name},update_by = #{userId} where id = #{id};

 每个业务sql都需要带入更新人,创建人信息。

用拦截器实现通用的逻辑,每个业务sql不再需要关心这两个字段,这两个字段的设置交给拦截器去做。

示例代码如下:

@Intercepts(value = {@Signature(type = Executor.class,method = "update",args = {MappedStatement.class,Object.class})})
public class MybatisAutoSetUserIdInterceptor implements Interceptor{
    
    //数据库字段对应的实体字段
    private static final String createBy = "createBy";
     //数据库字段对应的实体字段
    private static final String updateBy = "updateBy";

    public Object intercept(Invocation invocation) throws Throwable{

        Long userId = UserInfoThreadLocal.getUser();
        
        if(Objects.nonNull(userId)){
            
            MappedStatement statement = (MappedStatement)invocation.getArgs()[0];
            
            SqlCommandType sqlType = statement.getSqlCommandType();

            Object paramter = invocation.getArgs()[1];
            
            doSetUserIdWhenUpdate(sqlType,paramter,userId);

        }
          return invocation.proceed();

    }

    private void doSetUserIdWhenUpdate(SqlCommandType sqlType,Object paramter,Long userId){
         
       if(parameter instanceof Map){

            Map parameterMap = (Map)parameter;

            //批量更新
            if(parameterMap.containsKey("list")){

                List list = (List) parameterMap.get("list");

                list.forEach(e -> {
                    updateUserIdField(sqlType,e,userId);
                });

            }else{

                //单个更新
                updateUserIdField(sqlType,paramter,userId);

            }

        }

    }

    private void updateUserIdField(SqlCommandType commandType,Object obj,Long userId){

        Field[] fields = obj.getClass().getDeclaredFields();

        if(Objects.nonNull(obj.getClass().getSuperclass())){
            Field[] superFields = obj.getClass().getSuperclass().getDeclaredFields();
            fields = ArrayUtils.addAll(fields,superFields);
        }

        if(SqlCommandType.INSERT.equals(commandType)
             || SqlCommandType.UPDATE.equals(commandType)){

            Arrays.stream(fields)
                    .filter(e -> Objects.equals(createBy,e.getName()) || Objects.equals(updateBy,e.getName()))
                    .forEach(e -> {
                        e.setAccessible(true);
                        e.set(obj,userId);
                    });

        }

    }

    @Override
    public Object plugin(Object o){
        if(o instanceof Executor){
            return Plugin.wrap(o,this);
        }
        return o;
    }

    @Override
    public void setProperties(Properties properties){

    }
    
}

拦截器注入到容器中

@Configuration
public class MyBatisConfiguration{
    
    @Bean
    public MybatisAutoSetUserIdInterceptor mybatisAutoSetUserIdInterceptor(){


        return new MybatisAutoSetUserIdInterceptor();

     }

}

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值