meng框架

介绍

meng框架是一个实现了行数据权限和列数据权限的数据权限框架;
meng框架能让数据权限变成一个独立的功能模块,与业务模块完全分离,在已经实现的业务逻辑中添加数据权限不需要对原来的逻辑做任何改动;
meng框架配置简单,使用简单,实现原理简单;

配置简单:要实现行数据权限或列数据权限,只需要实现获取对应数据权限的接口即可,只有一个接口,可能也就一行代码;
使用简单:对需要进行数据权限控制的接口使用数据权限注解即可,且数据权限注解可能只需要指定数据实体类对应的表名就可轻松实现;
实现原理简单:授权器、数据权限注解、AOP数据过滤器

  1. 授权器获取当前用户拥有的数据权限
  2. 数据权限注解指定返回的数据属于哪张数据表
  3. AOP数据过滤器根据当前用户数据权限和数据权限注解指定表名过滤方法的返回值

注意:meng框架只实现数据过滤功能,获取当前用户数据权限时,如何获取当前用户信息(id),需要其他框架或者其他工具提供;

前提

使用meng框架的前提是必须提供行数据权限实体类或列数据权限实体类;

  1. 行数据权限表设计:id、表名、字段名、权限值(字段值)、······
  2. 列数据权限表设计:id、表名、字段名、······

再建立用户与两个数据权限表的关联关系就可以获取用户的数据权限了

什么是行数据权限?

行数据权限的效果是不同的用户,在相同查询条件下查询同一张表的数据,因他们的行数据权限不同,查到的数据条数也不同;
对于一张表来说,查询条件相同查询结果一定相同,让查询结果不同,只能添加额外的查询条件,额外查询条件是行数据权限给出的;
查询条件是什么?:某字段 等于 某值(meng框架只考虑等于);
那行数据权限是什么?:行数据权限是对数据表的字段的字段值抽象出来的实体,强调一下是【字段值】;
字段值拥有的属性:所在表、所在字段、值;

列数据权限

联系行数据权限,列数据权限实际上就是对数据表的字段抽象出来的实体
表字段拥有的属性:所在表、名称

meng框架的设计思路

如果您有过对数据权限比较深入研究,其实到这里这篇文档已经结束啦,meng框并不是代码写得有多好,核心东西是ta提供的数据权限设计表方案;
知道这个设计方案,数据权限就很简单了;
meng框架设计思路:

  1. 提供一个让开发者实现的抽象类,抽象方法是获取用户的所有数据权限;目的就是获取用户所有的数据权限;
  2. 由框架对用户所有的数据权限按表名进行分类
  3. 提供数据权限注解,注解在方法上,注解指定表名,表名对应方法返回的数据属于的那张表
  4. 提供一个切面切数据权限注解,通过注解指定的表名获取对应表的数据权限,然后方法返回结果进行数据过滤

使用步骤

1. 引入依赖

<dependency>
            <groupId>com.mlx</groupId>
            <artifactId>meng-spring-boot-starter</artifactId>
            <version>1.0.0</version>
        </dependency>

2. 实现授权器

2.1实现行数据权限授权器:获取当前用户的行数据权限,泛型参数是行数据权限实体类

@Component
public class MyRowPermission extends AbstractDataPermissionRowAuthorization<RowPermissionItem> {

    @Override
    protected Collection<RowPermissionItem> listUserDataPermissionRow() {
        RowPermissionItem item0 = new RowPermissionItem("BasProject", "departmentId", "6293D52A-78AD-48EA-B397-315267A522CD");
        RowPermissionItem item1 = new RowPermissionItem("bas_project", "department_id", "6293D52A-78AD-48EA-B397-315267A522CD");
        return Arrays.asList(item0, item1);
    }
}

2.2实现列数据权限授权器:获取当前用户的列数据权限,泛型参数是列数据权限实体类

@Component
public class MyColumnPermission extends AbstractDataPermissionColumnAuthorization<ColumnPermissionItem> {

    @Override
    protected Collection<ColumnPermissionItem> getColumnPermissions() {
        ColumnPermissionItem item0 = new ColumnPermissionItem("bas_project", "date_sign");
        ColumnPermissionItem item1 = new ColumnPermissionItem("bas_project", "project_status");
        ColumnPermissionItem item2 = new ColumnPermissionItem("bas_project", "leader_id");
        ColumnPermissionItem item3 = new ColumnPermissionItem("bas_project", "remark");
        ColumnPermissionItem item4 = new ColumnPermissionItem("bas_project", "project_name");

        ColumnPermissionItem item5 = new ColumnPermissionItem("BasProject", "dateSign");
        ColumnPermissionItem item6 = new ColumnPermissionItem("BasProject", "projectStatus");
        ColumnPermissionItem item7 = new ColumnPermissionItem("BasProject", "leaderId");
        ColumnPermissionItem item8 = new ColumnPermissionItem("BasProject", "remark");
        ColumnPermissionItem item9 = new ColumnPermissionItem("BasProject", "projectName");
        return Arrays.asList(item0, item1, item2, item3, item4, item5, item6, item7, item8, item9);
    }
}

3. 使用数据权限注解

@DataPermissionColumn(tableName = "BasProject")
    @DataPermissionRow(tableName = "BasProject")
    public List<BasProject> listSelective(BasProject query){
        List<BasProject> basProjects = mapper.listSelective(query);
        System.out.println("service数据量:" + basProjects.size());
        return basProjects;
    }

meng框架的不足

  1. 影响分页功能:列表查询时,类似于PageHelper的分页插件功能失效;
  2. 权限验证时,对数据类型中的小数类型支持不高,例:分辨不出2等于2.0;
  3. meng框架只支持权限值与数据值相等的比较(行数据权限)

结语

  1. meng框架影响分页功能只是因为选择的不同吧,在设计时就有两个选择,一是过滤方法返回值,二是改造sql语句添加数据权限查询条件;
    改在sql语句会依赖持久层框,不同的持久层框架可能需要不同的实现,或者说meng框架同时实现一个持久层框架,那也不可能呀;过滤方法返回值,现在想来,除了分页插件失效外,其他都还好;
  2. meng框架只支持权限值与数据值相等的比较本人觉得倒是挺好的;因为meng框架已经满足绝大多数需求了;
  3. 另一个框架meng2框架是一个基于权限值过滤规则的数据权限框架,可以解决相等比较和范围性比较的需求,先不说