文档章节

简洁常用权限系统的设计与实现(一):构造权限菜单树的N(N>=4)种方法

jtn
 jtn
发布于 2015/04/13 15:07
字数 998
阅读 14
收藏 0

 权限系统,Web开发常见标准子系统之一。结合自己的一些思考和实践,从本篇开始权限系统的设计与实现之路。

 最近,重构了项目的权限菜单构造过程,向前端返回json格式的权限树。

 这一篇,只是大致介绍下这个问题,并给出4种方法的整体思路,后续再分别详细介绍这4种方法,再往后介绍完整的权限系统的设计与实现。

 权限表的结构
 acl、parent_acl, 最重要的就是这2个字段,有了这2个字段,就可以构造一棵树了。

 前端需要的json格式:

"data":[{

        "acl":1,

        "children":[{

            "acl":11,

            "children":[{

                "acl":111,

            }]

        } 

方法1
   在数据库再增加1个level字段,最顶层的level就是1,每增加一级level增加1。

   先从数据库按照level升序,获得所有的权限节点。
            List<Map<String, Object>> rootList = new ArrayList<Map<String, Object>>(); 
  
           Map<String, Map<String, Object>> rootMap = new HashMap<String, Map<String, Object>>(); 
  
for (遍历) {
    

创建节点,加入到根节点map中

if (顶级节点) {

加入到rootList中

} else {

获得父结点,把自己放到父结点的children中

}

}

     遍历结束,rootList即为所求。

   这种方法是一个同事的思路,关键就是2点,一是维护level(增加和修改的时候都需要),2是要按照 level升序 排序。

方法2:数据库不需要level字段,用递归来实现。
    
List<Map<String, Object>> finalRootList = new ArrayList<Map<String, Object>>();

List<Map<String, Object>> rootList = findRootList(privilegeList);

List<Map<String, Object>> notRootList = findNotRootList(privilegeList);
               //先找出根节点,再为这些根节点构造子结点 

for (Map<String, Object> root : rootList) {

// 构造子结点

buildChildList(root, notRootList);

finalRootList.add(root);

}

    关键代码buildChildList是个递归函数。
   buildChildList(){
      从所有的非根节点中,找到当前节点的第1级子结点,加入到该节点的children中。
     buildChildList();
  } 

  好处是,不用维护level字段,增加和修改权限的时候,既不用维护level,也不用维护parent_acl。 


方法3:完全按照方法1的思路,唯一不同的是,数据库不维护level字段,而是在查询数据出来之后,手动计算每个节点的level字段,进行排序。后面的步骤,和方法1基本一样。

    因此,这种方法的唯一难点就是,如何计算一颗N叉树每一个节点的深度。

方法4:  计算一颗N叉树每一个节点的深度,经过实践,至少有2种方法。

a.按照方法2的递归思路,再维护一个level,向child深入一层,level++,返回level--。及时保存当前节点的level,递归结束,level就都计算完成。

b. 参照网上的一种思路,把“无序的Tree格式的List,转化打印出标准格式Treelist”。
  作者也是按照递归思路实现的,在这个代码的基础上,再维护1个level,就可以了。

a和b的思路相似的地方是,都在递归过程中维护1个level,不同的地方是,a的方法只单纯地计算level,而b不但计算了level,还把节点排序了。当然,a方法也是可以的。 


方法5:这种方法不可行,问题是,存在着重复计算的可能。
 所有节点初始level额外i1.
 找到所有的根节点。

  遍历每一个节点,如果发现自己有父结点,就把自己的level和所有父节点的level+1。
  
问题:无法保证多个子结点,都有子结点的时候,他们的父结点,重复增加了level,而重复计算的次数很难去统计。 


小雷FansUnion-博学的互联网技术工作者,提供付费的IT咨询服务
2014年11月17日

湖北-武汉-循礼门 

原文首发:http://fansunion.cn/article/detail/566.html

© 著作权归作者所有

jtn

jtn

粉丝 12
博文 879
码字总数 879609
作品 0
武汉
程序员
私信 提问
李玉宝/OpenAuth.Net

####项目简介: 项目采用经典DDD架构(用沃恩.弗农大神的话,其实这是DDD-Lite)思想进行开发,简洁而不简单,实用至上,并且所写每一行代码都经过深思熟虑,符合SOLID规则! 当然,如果你想学...

李玉宝
2015/12/03
0
0
领域驱动设计实战—基于DDDLite的权限管理OpenAuth.net

在园子里面,搜索一下“权限管理”至少能得到上千条的有效记录。记得刚开始工作的时候,写个通用的权限系统一直是自己的一个梦想。中间因为工作忙(其实就是懒!)等原因,被无限期搁置了。最...

银月光海
2016/01/07
221
0
权限管理系统 - OpenAuth.Net

项目采用经典DDD架构(用沃恩.弗农大神的话,其实这是DDD-Lite)思想进行开发,简洁而不简单,实用至上,并且所写每一行代码都经过深思熟虑,符合SOLID规则! 当然,如果你想学习完整的DDD框架...

李玉宝
2015/12/04
75.5K
51
RDIFramework.NET ━ .NET快速信息化系统开发框架钜献 V2.9 版本震撼发布

RDIFramework.NET ━ .NET快速信息化系统开发框架钜献 V2.9 版本震撼发布   全新体验、全新感觉、2015钜献! 继上个版本“RDIFramework.NET V2.8版本发布”5个多月的时间,V2.9版本面世了,...

yonghu86
2015/06/03
0
0
基于 Springboot 和 Mybatis 的后台管理系统--BootDo

项目介绍 面向学习型的开源框架,简洁高效,减少过渡封装,展现技术本质 Springboot作为基础框架,使用mybatis作为持久层框架 使用官方推荐的thymeleaf做为模板引擎,shiro作为安全框架,主流...

lcg0124
2017/09/12
152.8K
104

没有更多内容

加载失败,请刷新页面

加载更多

用原生js对表格排序

本文转载于:专业的前端网站➸用原生js对表格排序 阿里的模拟笔试题,当时时间有限没写出来,其实是因为自己对原生dom操作不熟悉,这里补一下。 题目的大意是有一个表格,如代码所示 <table>...

前端老手
36分钟前
5
0
IT兄弟连 HTML5教程 HTML5表单 HTML5新增表单元素

HTML5有一些新的表单元素:<datalist>、<keygen>、<output>。不是所有的浏览器都支持HTML5新的表单元素,但即使浏览器不支持该表单属性,仍然可以显示为常规的表单元素。 1 <datalist>元素 ...

老码农的一亩三分地
37分钟前
4
0
【朝花夕拾】Android自定义View篇之(一)View绘制流程

https://www.cnblogs.com/andy-songwei/p/10955062.html

shzwork
39分钟前
5
0
Qt编写自定义控件70-扁平化flatui

一、前言 对于现在做前端开发人员来说,FlatUI肯定不陌生,最近几年扁平化的设计越来越流行,大概由于现在PC端和移动端的设备的分辨率越来越高,扁平化反而看起来更让人愉悦,而通过渐变色产...

飞扬青云
48分钟前
3
0
教你玩转Linux—添加批量用户

添加和删除用户对每位Linux系统管理员都是轻而易举的事,比较棘手的是如果要添加几十个、上百个甚至上千个用户时,我们不太可能还使用useradd一个一个地添加,必然要找一种简便的创建大量用户...

Linux就该这么学
今天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部