mybatis 拦截器 添加参数_mybatis传递多个参数

mybatis 拦截器 添加参数_mybatis传递多个参数上一篇中讲了mybatis拦截器的实现这一篇扩展mybatis在拦截器中添加额外参数在mybatis的mapper.xml文件中,我们可以使用#{}或${}的方式获取到参数,这些参数都需要提前我们在mapper.java接口文件中通过参数的方式传入参数才能取到为了扩展参数,我们需要了解mybatis是怎么帮我们保管mapper.java中传入的参数的进入Executor.java接口查看query方法,可以看到第一个参数MappedStatement对象中有一个parameterMap字段,该字段是

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

上一篇中讲了mybatis拦截器的实现

这一篇扩展mybatis在拦截器中添加额外参数

在mybatis的mapper.xml文件中,我们可以使用#{}或${}的方式获取到参数,这些参数都需要提前我们在mapper.java接口文件中通过参数的方式传入参数才能取到

为了扩展参数,我们需要了解mybatis是怎么帮我们保管mapper.java中传入的参数的

进入Executor.java接口查看query方法,可以看到第一个参数MappedStatement对象中有一个parameterMap字段,该字段是Map类型保存我们的参数,那我们只需要在拦截器中对MappedStatement对象的parameterMap中put自己想要的参数即可

代码如下


/** * 部门数据拦截器 * * @author zhangxing * @date 2021/4/12 */
@Intercepts({ 
   
        @Signature(type = Executor.class, method = "query", args = { 
   MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}),
        @Signature(type = Executor.class, method = "query", args = { 
   MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class})
})
public class DeptDataScopeInterceptor implements Interceptor { 
   

    @Override
    public Object intercept(Invocation invocation) throws Throwable { 
   
        Object[] args = invocation.getArgs();

        if (ArrayUtils.isNotEmpty(args)) { 
   
            MappedStatement mappedStatement = (MappedStatement) args[0];
            DataScope dataScope = getDataScope(mappedStatement);

            StringBuilder sqlString = new StringBuilder();
            if (dataScope != null) { 
   
                Long companyOrgId = SecurityUtils.getCompanyOrgId();

                if (companyOrgId != null) { 
   
                    sqlString.append(StringUtils.format(" {}.{} = {} ", dataScope.orgAlias(), dataScope.orgColumnName(), companyOrgId));
                } else { 
   
                    sqlString.append(" 1=0 ");
                }
            }

            if (args[1] == null) { 
   
                args[1] = new MapperMethod.ParamMap<>();
            }
            Map map = (Map) args[1];
			// 此处为重点
            map.put("dataScope", sqlString.length() > 0 ? " (" + sqlString.toString() + ")" : "");
        }
        return invocation.proceed();
    }

    private DataScope getDataScope(MappedStatement mappedStatement) { 
   
        String id = mappedStatement.getId();
        // 获取 Class Method
        String clazzName = id.substring(0, id.lastIndexOf('.'));
        String mapperMethod = id.substring(id.lastIndexOf('.') + 1);

        Class<?> clazz;
        try { 
   
            clazz = Class.forName(clazzName);
        } catch (ClassNotFoundException e) { 
   
            return null;
        }
        Method[] methods = clazz.getMethods();

        DataScope dataScope = null;
        for (Method method : methods) { 
   
            if (method.getName().equals(mapperMethod)) { 
   
                dataScope = method.getAnnotation(DataScope.class);
                break;
            }
        }
        return dataScope;
    }

    @Override
    public Object plugin(Object target) { 
   
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) { 
   

    }

}

在map中加入dataScope后,即可在相应的mapper.xml中使用#{dataScope}或${dataScope}或取到该参数

如果项目中使用了pageHelper插件,则启动项目后,执行到对应的mapper查询的时候,如果mapper.xml中使用了上述方式添加的参数,那么项目会报错,因为pageHelper的拦截器会在我们的拦截器之前执行,pageHelper的拦截器中对参数进行了校验,因为自定的拦截器还没有执行,则Map中不会有自定义参数,当pageHelper的拦截器开始校验参数的时候就会报错找不到参数

如何将自定义的拦截器放在PageHelper拦截器前方执行
查阅资料后发现SqlSessionFactory中加入的拦截器,先加入的会后执行,后加入的先执行,那么我们需要让自定义的拦截器在PageHelper后加入,查看PageHelper的自动配置类
在这里插入图片描述
pageHelper的拦截器会在Mybatis的自动配置后在做相应配置,那么我们可以写一个配置类,让他在PageHelper的配置类后再执行

代码如下

/** * @author zhangxing * @date 2021/4/11 */
@Configuration
@ConditionalOnBean({ 
   SqlSessionFactory.class})
@AutoConfigureAfter(PageHelperAutoConfiguration.class)
public class DeptDataScopeInterceptorConfig { 
   

    @Autowired
    private List<SqlSessionFactory> sqlSessionFactoryList;

    @PostConstruct
    public void addPageInterceptor() { 
   
        DeptDataScopeInterceptor interceptor = new DeptDataScopeInterceptor();
        for (SqlSessionFactory sqlSessionFactory : sqlSessionFactoryList) { 
   
            sqlSessionFactory.getConfiguration().addInterceptor(interceptor);
        }
    }

}

此处需要注意的是,如果DeptDataScopeInterceptorConfig配置类会被SpringBoot项目自动扫描到,尽管配置的顺序是在PageHelper自动配置后再配置,但是被SpringBoot扫描到的配置类会优先加载,所以要防止SpringBoot扫描带该配置,有如下几种方案

  • 如果该配置类已经会被扫描到,则可以使用排出的方式排除掉该类,然后用spring.factories的方式做自动配置
    可以使用@SpringBootApplication(exclude = DeptDataScopeInterceptorConfig.class)
    @ComponentScan(excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = DeptDataScopeInterceptorConfig.class))
    @EnableAutoConfiguration(exclude = DeptDataScopeInterceptorConfig.class)的方式排出,然后添加到spring.factories中
    文件路径地址resrouces/META-INF/spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  top.sclf.common.datascope.config.DeptDataScopeInterceptorConfig
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/197765.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • c#savefiledialog默认文件名_visual studio code保存快捷键

    c#savefiledialog默认文件名_visual studio code保存快捷键SaveFileDialogsaveFileDialog=newSaveFileDialog();//打开的文件选择对话框上的标题saveFileDialog.Title=”请选择文件”;//设置文件类型saveFileDialog.Filter=”文本文件(*.txt)|*.txt|所有文件(*.*)|*.*”;//设置默认文件类型显示顺序saveFileDialog

    2022年10月8日
    0
  • adb出现adb server is out of date时的解决的方法「建议收藏」

    adb出现adb server is out of date时的解决的方法「建议收藏」出错的原因是adb的port被其它程序的进程占据了,所以要做的就是找到并kill该进程。步骤:、1、在cmd中运行adbnodaemonserver,查看adb的port号是多少,普通情况下是50

    2022年7月2日
    49
  • 女生学java软件开发怎么样?就业前景如何?

    女生学java软件开发怎么样?就业前景如何?学java目前现状是男生多于女生,从事java工作的也是男生多于女生,那么这种现状是说女生学java不好找工作吗?​  一、女生适合从事java吗?  在很多人的潜意识里,认为女生是不适合从事java工作的,因为他们觉得从事java工作的人逻辑性要相当的好,并且专业操作水平要高,而女生往往在这方面比较弱。其实这只是一种偏见,就像古代人觉得女子不该干涉朝政一样,女生也是适合从事java工作的,并且还能发挥自己的优势把java工作做得更好。  二、女生学java好找工作吗?  1.现在的女生

    2022年7月9日
    25
  • HTTP 500 Internal Server Error[通俗易懂]

    HTTP 500 Internal Server Error[通俗易懂]HTTP500InternalServerError

    2022年7月14日
    14
  • python运维开发实战「建议收藏」

    python运维开发实战「建议收藏」python运维和开发实战-基础篇python运维和开发实战-基础篇课程链接如下:通过如下链接地址购买课程可享受优惠哈~限时优惠,原价499元,现价只需125元https://edu….

    2022年7月12日
    19
  • chegg网站_chunked

    chegg网站_chunked服务端给浏览器发送报文时,必须告诉浏览器报文的大小,这样浏览器可以根据报文大小来判断报文的完整性以及在长连接中确定报文的截尾。但是很多服务器的报文是动态创建的,在发送之前是无法确定其大小的。服务器只有等待内容全部创建后,计算出主体的大小,才能响应客户端的请求,这样的处理方法大大延迟了响应。传输编码中的分块编码为这种困难提供了解决方案,服务器可以逐块发送主体,并说明每块的大小就可以了。HTTP协议中

    2025年8月1日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号