后台实现多级权限树结构

hl.wang

发布于 2018.12.21 22:40 阅读 2650 评论 0

提出问题:当你写一个项目的时候基本上都需要写权限管理,有时候权限管理需要在后台形成树结构,如果只是固定层级的树结构还比较好些,但是遇到哪些不是固定需要动态增加层级的应该如何写呢并给让他与数据库建立的链接尽可能的少呢?

 

 

分析问题如果我们能先拿到根节点,然后根据根节点拿到所有的子节点,然后在将拿到的子节点模拟为数据库,来加到父节点,下面我们来看一下到底要如何实现

 

 

样例:

  1. 首先设计数据库的表的结构:

要类似于这样,如果是根节点我们让parent_permission_id0,如果不是就设为他的父节点的id,parent_Code,如果是根节点就设为null,如果不是就按照如上设计,这样是方便你查询到根节点所有的子节点

 

 

 

 

  1. 数据库表的结构设计好了,那么具体实现该如何写呢下面我们来看:
List<SvnPermissionDTO> svnUserPermissionDTOList = svnPermissionService.selectByExample(svnPermission,rowBounds);
List<SvnPermissionDTO> svnPermissionDTOs = new ArrayList<SvnPermissionDTO>();
//生成树形结构
for(SvnPermissionDTO svnPermissionDTO:svnUserPermissionDTOList) {
    if (svnPermissionDTO != null) {
        if (svnPermissionDTO.getParentPermissionId() != null &&svnPermissionDTO.getParentPermissionId() == 0) {
            SvnPermissionDTO svnPermissionDTO1 = svnPermissionService.selectChild(svnPermissionDTO);
            svnPermissionDTOs.add(svnPermissionDTO1);
        }
    }
}

 

 

 

 

首先我们通过查询数据库将所有的信息放到一个List中,样例中是都放到了svnUserPermissionDTOList这个集合中,然后遍历这个集合,我们防止数据重复,所以是通过根节点找他的子节点,所以当我们判断这个节点是根节点的时候,就让他执行selectChild方法,然后下面我们来看一下这个方法的实现:

 

public SvnPermissionDTO selectChild(SvnPermissionDTO svnPermissionDTO) {
    List<SvnPermissionDTO> svnPermissionDTOList = selectChildByParentCode(svnPermissionDTO.getId()+"-");
    if(svnPermissionDTOList != null){
        //查询下一级子节点
        List<SvnPermissionDTO> svnPermissionDTO1 = selectChildByALLChild(svnPermissionDTOList,svnPermissionDTO);
        if(svnPermissionDTO1.size() != 0){
            //有下一级子节点的话遍历子节点
            for(SvnPermissionDTO svnPermissionDTO2:svnPermissionDTO1){
                if(svnPermissionDTO2 != null){
                    //通过一个中间对象来接受递归返回的对象
                    SvnPermissionDTO  temp =  selectChild(svnPermissionDTO2);
                    //将递归返回的对象加到他的上一级父节点上
                    svnPermissionDTO.getChildren().add(temp);
                }else {
                    return  svnPermissionDTO;
                }
            }
        }
    }
   return svnPermissionDTO;
}

 

 

 

这个方法首先根据传进来的根节点对象,通过Pcode模糊查询到所有的子节点放到一个List集合中,如果这个集合不是null说明这个根节点有子节点,我们就继续找他的子节点,下面我们遍历了他这个子节点集合然后调用了一个selectChildByALLChild方法,然后我们来看一下这个方法的实现:

 

public List<SvnPermissionDTO> selectChildByALLChild(List<SvnPermissionDTO> svnPermissionDTOList,SvnPermissionDTO svnPermissionDTO) {
    List<SvnPermissionDTO> svnPermissionDTOs = new ArrayList<SvnPermissionDTO>();
    if(svnPermissionDTOList.size() != 0){
        if(svnPermissionDTO != null){
            //遍历所有子节点集合
            for(SvnPermissionDTO svnPermissionDTO1:svnPermissionDTOList){
                //如果有子节点就加到集合中去
                if(svnPermissionDTO1.getParentPermissionId() == svnPermissionDTO.getId()){
                    svnPermissionDTOs.add(svnPermissionDTO1);
                }
            }
        }
    }
    return svnPermissionDTOs;
}

 

 

 

这个方法接受了一个List集合,他接受的时候我们之前通过Pcode查询到的所有子节点,这个方法就是用来模拟数据库,将每次查询数据库换成了调用这个方法来减少对数据库的链接,我们可以看见她还接收了一个对象,这个方法的作用就是传进来的这个对象如果没有下一级子节点返回的集合里的size就是0,具体用法规则请看仔细看代码注释。

 

 

 

 

 

总结:该方法不但实现了无论多少级的树形结构都可以显示出来,并且避免了递归调用频繁的链接数据库,主要思想就是:用一个方法接收通过Pcode查询的所有的子节点,通过调用这个方法来避免查询数据库,避免频繁连接数据库