美文网首页
mybatis 拦截器

mybatis 拦截器

作者: 分布式与微服务 | 来源:发表于2022-10-21 09:00 被阅读0次

    在mybatis中可被拦截的类型有四种(按照拦截顺序):

    1.Executor:拦截执行器的方法。
    2.ParameterHandler:拦截参数的处理。
    3.ResultHandler:拦截结果集的处理。
    4.StatementHandler:拦截Sql语法构建的处理。
    其实Executor都可以实现ParameterHandler,ResultHandler,StatementHandler拦截器的功能

    拦截器一般在业务处理中用于:

    1、分页查询

    2、多租户添加条件过滤

    3、对返回结果,过滤掉审计字段,敏感字段

    4、对返回结果中的加密数据进行解密

    5、对新增数据自动添加创建人,创建时间,更新时间,更新人 ,对更新数据自动新增更新时间,更新人

    现在来用拦截器是实现需求5:

    package com.fen.dou.inceptor;
     
    import com.fen.dou.entity.BaseEntity;
    import com.fen.dou.entity.User;
    import lombok.extern.slf4j.Slf4j;
    import org.apache.ibatis.executor.Executor;
    import org.apache.ibatis.mapping.MappedStatement;
    import org.apache.ibatis.mapping.SqlCommandType;
    import org.apache.ibatis.plugin.*;
     
    import java.util.Map;
    import java.util.Properties;
    @Slf4j
    @Intercepts( {@Signature(type = Executor.class,method = "update",args = {MappedStatement.class,Object.class})})
    @Component
    public class MyExecutor implements Interceptor {
        @Override
        @SuppressWarnings("unchecked")
        public Object intercept(Invocation invocation) throws Throwable {
            // 根据签名指定的args顺序获取具体的实现类
            // 1. 获取MappedStatement实例, 并获取当前SQL命令类型
            MappedStatement ms = (MappedStatement) invocation.getArgs()[0];
            SqlCommandType commandType = ms.getSqlCommandType();
     
            // 2. 获取当前正在被操作的类, 有可能是Java Bean, 也可能是普通的操作对象, 比如普通的参数传递
            // 普通参数, 即是 @Param 包装或者原始 Map 对象, 普通参数会被 Mybatis 包装成 Map 对象
            // 即是 org.apache.ibatis.binding.MapperMethod$ParamMap
            Object parameter = invocation.getArgs()[1];
            // 获取拦截器指定的方法类型, 通常需要拦截 update
            String methodName = invocation.getMethod().getName();
            log.info("NormalPlugin, methodName; {}, commandType: {}", methodName, commandType);
     
            // 3. 获取当前用户信息
            User user = new User(1,"yangcai","sssss");
            // 默认测试参数值
            int creator = 2, updater = 3;
     
            if (parameter instanceof BaseEntity) {
                // 4. 实体类
                BaseEntity entity = (BaseEntity) parameter;
                if (user != null) {
                    creator = entity.getCreator();
                    updater = entity.getUpdater();
                }
                if (methodName.equals("update")) {
                    if (commandType.equals(SqlCommandType.INSERT)) {
                        entity.setCreator(creator);
                        entity.setUpdater(updater);
                        entity.setCreateTime(System.currentTimeMillis());
                        entity.setUpdateTime(System.currentTimeMillis());
                    } else if (commandType.equals(SqlCommandType.UPDATE)) {
                        entity.setUpdater(updater);
                        entity.setUpdateTime(System.currentTimeMillis());
                    }
                }
            } else if (parameter instanceof Map) {
                // 5. @Param 等包装类
                // 更新时指定某些字段的最新数据值
                if (commandType.equals(SqlCommandType.UPDATE)) {
                    // 遍历参数类型, 检查目标参数值是否存在对象中, 该方式需要应用编写有一些统一的规范
                    // 否则均统一为实体对象, 就免去该重复操作
                    Map map = (Map) parameter;
                    if (map.containsKey("creator")) {
                        map.put("creator", creator);
                    }
                    if (map.containsKey("updateTime")) {
                        map.put("updateTime",System.currentTimeMillis());
                    }
                }
            }
            // 6. 均不是需要被拦截的类型, 不做操作
            return invocation.proceed();
        }
     
        @Override
        public Object plugin(Object target) {
            return Plugin.wrap(target, this);
        }
     
        @Override
        public void setProperties(Properties properties) {
        }
    }
    

    其实这个也可以用 ParameterHandler来实现,拦截器底层是用了jdk动态代理

    相关文章

      网友评论

          本文标题:mybatis 拦截器

          本文链接:https://www.haomeiwen.com/subject/gqrwwrtx.html