当前位置: 首页 > article >正文

mybatisPlus拦截sql失败----已解决

1. 在使用MybatisPlusInterceptor想对数据权限做限制,但是发现使用寻常的配置,在执行sql后也不会被拦截 代码如下:

@Configuration public class MybatisPlusConfig { public MybatisPlusInterceptor setMybatisPlusInterceptor(){ MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new DataPermissionInterceptor(new MyDataPermissionHandler())); return interceptor; }
}

执行sql语句后拦截器没有反应

@Slf4j
public class MyDataPermissionHandler implements DataPermissionHandler {

    @Override
    @SneakyThrows
    public Expression getSqlSegment(Expression where, String mappedStatementId) {
        // 超级管理员不受数据权限控制

        Class<?> clazz = Class.forName(mappedStatementId.substring(0, mappedStatementId.lastIndexOf(StringPool.DOT)));
        String methodName = mappedStatementId.substring(mappedStatementId.lastIndexOf(StringPool.DOT) + 1);
        Method[] methods = clazz.getDeclaredMethods();
        for (Method method : methods) {
            DataPermission annotation = method.getAnnotation(DataPermission.class);
            if (ObjectUtils.isNotEmpty(annotation)
                    && (method.getName().equals(methodName) || (method.getName() + "_COUNT").equals(methodName))) {

                return dataScopeFilter(annotation.dataScope(), annotation.deptAlias(), annotation.deptIdColumnName(), annotation.userAlias(), annotation.userIdColumnName(), where);
            }
        }
        return where;
    }


    /**
     * 构建过滤条件
     *
     * @param where 当前查询条件
     * @return 构建后查询条件
     */
    @SneakyThrows
    public static Expression dataScopeFilter(DataPermissionEnum dataScopeEnum, String deptAlias, String deptIdColumnName, String userAlias, String userIdColumnName, Expression where) {


        String deptColumnName = StrUtil.isNotBlank(deptAlias) ? (deptAlias + StringPool.DOT + deptIdColumnName) : deptIdColumnName;
        String userColumnName = StrUtil.isNotBlank(userAlias) ? (userAlias + StringPool.DOT + userIdColumnName) : userIdColumnName;

        TspUserInfo tspUserInfo = ThreadContext.getSubject();
        if (dataScopeEnum == null) {
            String dataPermission = tspUserInfo.getDataPermission();
            // 获取当前用户的数据权限
            dataScopeEnum = DataPermissionEnum.getByCode(dataPermission);
        }

        //部门ID 包含多个部门,同一个用户的部门来源于用户组
        String orgCode = tspUserInfo.getOrgCode();
        String userId = tspUserInfo.getUserId();
        String acctOrgCode = tspUserInfo.getAcctOrgCode();
        List<String> dataPermissionOrgCodes = tspUserInfo.getDataPermissionOrgCodes();
        String appendSqlStr;
        switch (Objects.requireNonNull(dataScopeEnum)) {
            case Org:
//                appendSqlStr = deptColumnName + " in (" + orgCode + ")";
                appendSqlStr = deptColumnName + StringPool.EQUALS + orgCode;
                break;
            case Personal:
                appendSqlStr = userColumnName + StringPool.EQUALS + userId;
                break;
            case AcctOrg:
                appendSqlStr = userColumnName + StringPool.EQUALS + acctOrgCode;
                break;
            // 默认部门及子部门数据权限
            default:
                appendSqlStr = deptColumnName + " in (" + String.join(",", dataPermissionOrgCodes) + ")";
                break;
        }


        if (StrUtil.isBlank(appendSqlStr)) {
            return where;
        }

        Expression appendExpression = CCJSqlParserUtil.parseCondExpression(appendSqlStr);

        if (where == null) {
            return appendExpression;
        }

        return new AndExpression(where, appendExpression);
    }


}

2. 就认为是拦截器没有起作用,后面同事大哥给了一个解决方法

@Slf4j
public class SqlSessionFactoryBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof SqlSessionFactory) { //所有bean初始化之后都会进入这个方法,这个时候需要滤出需要的类型,比如这次就只需要拿到SqlSessionFactory类型的对象对其设置拦截器就行了
            SqlSessionFactory nowBean = (SqlSessionFactory) bean;
            nowBean.getConfiguration().addInterceptor(new RowVersionUpdateInterceptor());
            nowBean.getConfiguration().addInterceptor(setMybatisPlusInterceptor());
        }
        return bean; //完成后返回出去,可能直接进入容器,也可能会去执行其他的BeanPostProcessor
    }
    public MybatisPlusInterceptor setMybatisPlusInterceptor(){
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new DataPermissionInterceptor(new MyDataPermissionHandler()));
        return interceptor;
    }
}

直接在注册Bean的时候,将SqlSessionFactory相关的bean都加上拦截器,然后再把SqlSessionFactoryBeanPostProcessor 注册到ioc中

@Configuration
public class MybatisPlusConfig {

    @Bean
    public SqlSessionFactoryBeanPostProcessor sqlSessionFactoryBeanPostProcessor() {
        return new SqlSessionFactoryBeanPostProcessor();
    }
}

3.可以解决问题,但是又不知道这个问题出在哪里,因为我之前都是这样配的,且重新搭建一个新的环境按照原来的方法依然可以,等我了解后问题,在来加更。。。。。。


http://www.kler.cn/a/466652.html

相关文章:

  • 【网络协议】IPv4 地址分配 - 第一部分
  • Zookeeper是如何解决脑裂问题的?
  • flutter在windows平台中运行报错
  • Docker新手:在tencent云上实现Python服务打包到容器
  • 【Unity Shader】【图形渲染】Unity Shader操作基础5-Unity Shader调试技巧
  • zsh 配置备忘
  • basic-validation-using-flask-gladiator-module-in-python
  • APM 3.0.2 | 聚合B站、油管和MF的音乐播放器,支持歌词匹配
  • 2025 小模型技术:驱动低代码与物联网融合发展新引擎
  • Markdown段落的空行缩进用法
  • STM32 拓展 RTC(实时时钟)
  • 前端,npm install安装依赖卡在sill idealTree buildDeps(设置淘宝依赖)
  • ElasticSearch11-8.x 新特性
  • JupyterLab notebook环境在Ubuntu24.04下的安装和Windows 10下vscode远程使用jupyter
  • 鸿蒙应用开发搬砖经验之—使用DevTools工具调试前端页面
  • SpringBoot + Vue 项目创建详细步骤
  • BERT算法实现SQuAD问答系统任务和IMDB文本分类任务
  • uniapp 微信小程序 自定义日历组件
  • LiveData 原理分析
  • OpenSSL SSL_connect: Connection was reset in connection to github.com:443
  • 图像去雾 | 基于Matlab的图像去雾系统(四种方法)
  • 【开源】创建自动签到系统—QD框架
  • Statistic for ML
  • 《Java核心技术II》管道化Optional值
  • Flutter中的网络请求图片存储为缓存,与定制删除本地缓存
  • 涡度通量/数据质量控制/数据缺失插补/数据组分拆分/数据可视化分析/气象数据/光敏感性分析/温度敏感性分析/数据风浪区分析