简洁常用权限系统的设计与实现(一):构造权限菜单树的N(N>=4)种方法
2014-12-17 20:20
387 查看
权限系统,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
最近,重构了项目的权限菜单构造过程,向前端返回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
相关文章推荐
- 简洁常用权限系统的设计与实现(一):构造权限菜单树的N(N>=4)种方法
- 简洁经常使用权限系统的设计与实现(一):构造权限菜单树的N(N>=4)种方法
- 简洁常用权限系统的设计与实现(一):构造权限菜单树的N(N>=4)种方法
- 简洁常用权限系统的设计与实现(一):构造权限菜单树的N(N>=4)种方法
- 简洁常用权限系统的设计与实现(七):一种错误的不可行的构造树的方法
- 简洁常用权限系统的设计与实现(七):一种错误的不可行的构造树的方法
- 简洁常用权限系统的设计与实现(七):一种错误的不可行的构造树的方法
- 简洁常用权限系统的设计与实现(七):一种错误的不可行的构造树的方法
- 简洁常用权限系统的设计与实现(四):不维护level,用递归方式构造树
- 简洁常用权限系统的设计与实现(六):不维护节点的深度level,手动计算level,构造树 (把一颗无序的树,变成有序的)
- 简洁常用权限系统的设计与实现(六):不维护节点的深度level,手动计算level,构造树 (把一颗无序的树,变成有序的)
- 简洁常用权限系统的设计与实现(三):维护和利用节点的深度level,迭代实现树的构造
- 简洁常用权限系统的设计与实现(四):不维护level,用递归方式构造树
- 简洁常用权限系统的设计与实现(四):不维护level,用递归方式构造树
- 简洁常用权限系统的设计与实现(三):维护和利用节点的深度level,迭代实现树的构造
- 简洁常用权限系统的设计与实现(三):维护和利用节点的深度level,迭代实现树的构造
- 简洁常用权限系统的设计与实现(六):不维护节点的深度level,手动计算level,构造树 (把一颗无序的树,变成有序的)
- 简洁常用权限系统的设计与实现(六):不维护节点的深度level,手动计算level,构造树 (把一颗无序的树,变成有序的)
- 简洁常用权限系统的设计与实现(三):维护和利用节点的深度level,迭代实现树的构造
- 简洁常用权限系统的设计与实现(四):不维护level,用递归方式构造树