iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >怎么用Springboot+mybatis-plus+注解实现数据权限隔离
  • 381
分享到

怎么用Springboot+mybatis-plus+注解实现数据权限隔离

2023-06-08 07:06:23 381人浏览 薄情痞子
摘要

今天小编给大家分享一下怎么用SpringBoot+mybatis-plus+注解实现数据权限隔离的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们

今天小编给大家分享一下怎么用SpringBoot+mybatis-plus+注解实现数据权限隔离的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。

1.创建注解

当此注解打在类上,不需要传参,该类下所有查询接口开启数据隔离;打在方法上默认开启数据隔离,传参为false则该方法关闭验证

@Documented@Target({METHOD, ANNOTATioN_TYPE, TYPE})@Retention(RUNTIME)public @interface DataPermission {        boolean isPermi() default true;}

2. 具体实现

@Component@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})})public class DataPermissionInterceptor implements Interceptor {    private static final Logger logger = LoggerFactory.getLogger(DataPermissionInterceptor.class);    @Autowired    private TokenService tokenService;    //扫描的包路径(根据自己的项目路径来),这里是取的配置里的包路径    @Value("${permission.package-path}")    private String packagePath;    private final static String DEPT_ID = "dept_id";    private final static String USER_ID = "create_user";    private static List<String> classNames;    @Override    public Object intercept(Invocation invocation) throws Throwable {        try {            LoginInfo user = tokenService.getLoginInfo();            if (user == null){                return invocation.proceed();            }            List<Long> deptIds = (List<Long>) Convert.toList(user.getDataScope());            if (deptIds == null){                deptIds = new ArrayList<>();            }            //反射扫包会比较慢,这里做了个懒加载            if (classNames == null) {                synchronized (LazyInit.class){                    if (classNames == null){                        //扫描指定包路径下所有包含指定注解的类                        Set<Class<?>> classSet = ClassUtil.scanPackageByAnnotation(packagePath, DataPermission.class);                        if (classSet == null && classSet.size() == 0){                            classNames = new ArrayList<>();                        } else {                            //取得类全名                            classNames =  classSet.stream().map(Class::getName).collect(Collectors.toList());                        }                    }                }            }            // 拿到mybatis的一些对象            StatementHandler statementHandler = PluginUtils.realTarget(invocation.getTarget());            MetaObject metaObject = SystemMetaObject.forObject(statementHandler);            MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");            // mappedStatement.getId()为执行的mapper方法的全路径名,newId为执行的mapper方法的类全名            String newId = mappedStatement.getId().substring(0, mappedStatement.getId().lastIndexOf("."));            // 如果不是指定的方法,直接结束拦截            if (!classNames.contains(newId)) {                return invocation.proceed();            }            String newName = mappedStatement.getId().substring(mappedStatement.getId().lastIndexOf(".") + 1, mappedStatement.getId().length());            //是否开启数据权限            boolean isPermi = true;            Class<?> clazz = Class.forName(newId);            //遍历方法            for (Method method : clazz.getDeclaredMethods()) {                //方法是否含有DataPermission注解,如果含有注解则将数据结果过滤                if (method.isAnnotationPresent(DataPermission.class) && newName.equals(method.getName())) {                    DataPermission dataPermission =  method.getAnnotation(DataPermission.class);                    if (dataPermission != null) {                        //不验证                        if (!dataPermission.isPermi()) {                            isPermi = false;                        } else { //开启验证                            isPermi = true;                        }                    }                }            }            if (isPermi){                // 获取到原始sql语句                String sql = statementHandler.getBoundSql().getSql();                // 解析并返回新的SQL语句,只处理查询sql                if (mappedStatement.getSqlCommandType().toString().equals("SELECT")) {    //                    String newSql = getNewSql(sql,deptIds,user.getUserId());                    sql = getSql(sql,deptIds,user.getUserId());                }                // 修改sql                metaObject.setValue("delegate.boundSql.sql", sql);            }            return invocation.proceed();        } catch (Exception e){            logger.error("数据权限隔离异常:", e);            return invocation.proceed();        }    }                private String getSql(String sql,List<Long> deptIds,Long userId) {        try {            String condition = "";            String permissionSql = "(";            if (deptIds.size() > 0){                for (Long deptId : deptIds) {                    if ("(".equals(permissionSql)){                        permissionSql = permissionSql + deptId;                    } else {                        permissionSql = permissionSql + "," + deptId;                    }                }                permissionSql = permissionSql + ")";                // 修改原语句                condition = DEPT_ID +" in " + permissionSql;            } else {                condition = USER_ID +" = " + userId;            }            if (StringUtils.isBlank(condition)){                return sql;            }            Select select = (Select)CCjsqlParserUtil.parse(sql);            PlainSelect plainSelect = (PlainSelect)select.getSelectBody();            //取得原SQL的where条件            final Expression expression = plainSelect.getWhere();            //增加新的where条件            final Expression envCondition = CCJSqlParserUtil.parseCondExpression(condition);            if (expression == null) {                plainSelect.setWhere(envCondition);            } else {                AndExpression andExpression = new AndExpression(expression, envCondition);                plainSelect.setWhere(andExpression);            }            return plainSelect.toString();        } catch (JSQLParserException e) {            logger.error("解析原SQL并构建新SQL错误:" + e);            return sql;        }    }

以上就是“怎么用springboot+mybatis-plus+注解实现数据权限隔离”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注编程网精选频道。

--结束END--

本文标题: 怎么用Springboot+mybatis-plus+注解实现数据权限隔离

本文链接: https://www.lsjlt.com/news/252695.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Springboot+mybatis-plus+注解实现数据权限隔离
    目录1.创建注解 2. 具体实现 1.创建注解 当此注解打在类上,不需要传参,该类下所有查询接口开启数据隔离;打在方法上默认开启数据隔离,传参为false则该方法关闭验证 @...
    99+
    2022-11-12
  • 怎么用Springboot+mybatis-plus+注解实现数据权限隔离
    今天小编给大家分享一下怎么用Springboot+mybatis-plus+注解实现数据权限隔离的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们...
    99+
    2023-06-08
  • MyBatis-Plus 使用拦截器实现数据权限控制
    前言背景 平时开发中遇到根据当前用户的角色,只能查看数据权限范围的数据需求。列表实现方案有两种,一是在开发初期就做好判断赛选,但如果这个需求是中途加的,或不希望每个接口都加一遍,就可以方案二加拦截器的...
    99+
    2023-09-07
    mybatis java
  • SpringBoot和Vue.js怎么实现前后端分离的用户权限管理系统
    这篇文章主要介绍“SpringBoot和Vue.js怎么实现前后端分离的用户权限管理系统”,在日常操作中,相信很多人在SpringBoot和Vue.js怎么实现前后端分离的用户权限管理系统问题上存在疑惑,小编查阅了各式资料,整理出简单好用的...
    99+
    2023-07-05
  • SpringBoot怎么整合Springsecurity实现数据库登录及权限控制
    这篇文章主要为大家展示了“SpringBoot怎么整合Springsecurity实现数据库登录及权限控制”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“SpringBoot怎么整合Springs...
    99+
    2023-06-22
  • springboot怎么集成@DS注解实现数据源切换
    这篇文章主要介绍“springboot怎么集成@DS注解实现数据源切换”,在日常操作中,相信很多人在springboot怎么集成@DS注解实现数据源切换问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”sprin...
    99+
    2023-06-29
  • 怎么使用MyBatisPlus拦截器实现数据权限控制
    这篇文章主要介绍“怎么使用MyBatisPlus拦截器实现数据权限控制”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“怎么使用MyBatisPlus拦截器实现数据权限控制”文章能帮助大家解决问题。前言...
    99+
    2023-07-05
  • python怎么用ChatGPT读取.env实现文件配置隔离保障私有数据安全
    这篇文章主要介绍了python怎么用ChatGPT读取.env实现文件配置隔离保障私有数据安全的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇python怎么用ChatGPT读取.env实现文件配置隔离保障私有数...
    99+
    2023-07-05
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作