概述
一直忙于工作很久没有抽出时间写博客了,最近有点闲暇时间,接触到了一些层级数据,需求要求生成树,先大体看一下如下的数据层级,大体分为5个层级,分别是5是4的子节点,4是3的子节点,3是2的子节点,2是1的子节点,1是根节点,
要求生成类似level1下挂level2的数据格式,前端拿到后就能生成类似目录层级的数据了
解决办法
如何做呐?首先考虑一个问题是树的生成在mysql5.x版本中是无法直接生成的,所以基本上就只能将数据取出来在java端对树进行生成
首先生成一个类AreaVo ,这个AreaVo中有一个包含自己的List
@Getter
@Setter
@ToString
public class AreaVo extends Area{
private List<AreaVo> areaChildList = new ArrayList();
}
接下来看看是如何生成树的,大体步骤都在注释中,末尾会有个小总结,读者,可以根据需要看看
@GetMapping
public Response areaInfoService(){
//我们首先通过service获取库中的所有数据
List<Area> areas = areaService.list();
//将数据转换为上面我们创建的vo,至于为什么要有一个vo继承Area其间又有一个包含自己的List
//能给出的答案是,在与service相关的entity,自有其作用,创建vo是为了能够让它即有Area的属性
//又能将子类挂在其中,又或许是单一职责的原则让我们这样设计这个vo
List<AreaVo> areaVos = areas.stream().map(e -> {
AreaVo areaVo = new AreaVo();
BeanUtils.copyPropertiesIgnoreNull(e, areaVo);
return areaVo;
}
).collect(Collectors.toList());
return Response.success(findRootList(areaVos));
}
private List<AreaVo> findRootList(List<AreaVo> areaVos) {
//通过List Stream 过滤出根节点的List
List<AreaVo> rootLists = areaVos.stream().filter(e -> e.getLevel() == 1).collect(Collectors.toList());
//最后一步将List转为vo
listTransferToTree(areaVos,rootLists,1);
return rootLists;
}
private void listTransferToTree(List<AreaVo> areaVos,List<AreaVo> rootLists,Integer level) {
for (AreaVo areaVo: rootLists){
Integer nextLevel = level+1;
//筛出下一层级的数据并且要取得parentId和当前根节点id一样的数据,
//也就是当前根节点的子节点
List<AreaVo> nextRootLevelAreaInfo =
areaVos.stream().filter(e -> e.getLevel().equals(nextLevel) && e.getParentId().equals(areaVo.getId())).collect(Collectors.toList());
//将子节点挂到符层级下
areaVo.setAreaInfoCopy1VoList(nextRootLevelAreaInfo);
//递归寻找子节点下的下一个子节点,直到所有节点全部被搜寻完
listTransferToTree(areaInfoCopy1Vos,nextRootLevelAreaInfo,nextLevel);
}
}
我们的大体思路是遍历每一个根节点,尝试在层级中获取该根节点的子层级节点,如果该根节点的子层级节点存在,那么,将该子层级节点存放在根节点的层级中,然后以该根节点的子层级节点为根节点,寻找该根节点的子层级节点,如果该根节点的子层级节点存在,那么,将该子层级节点存放在根节点的层级中,然后以该根节点的子层级节点为根节点,寻找该根节点的子层级节点,如此反复,直到将所有节点遍历完为止,根节点存在子节点,就挂到根节点上,以该根节点的子节点为根节点,再次调用这个函数寻找子节点,直到所有节点遍历完为止,当所有节点遍历完了,根节点下的所有子节点都挂到根节点下了,所以整颗树也就成形了,所以从List到树的转化过程也就完成了
大体这样,除了树之外我们还会涉及到一个权限的验证,它的大体意思是,一个用户可以对应多个角色,一个角色可以对应多个用户,一个角色可以对应多个权限,一个权限可以分给多个角色,那么当请求过来的时候,我们就可以在数据库中取到当前用户用户的角色及角色对应的权限,当我们拿到用户的权限的时候,就可以在拦截器端验证这些模块用户是否能访问,不能访问的则给出用户无权访问的页面即可,权限验证的思路大体是这样的,往后吧,有时间再看看这部分的博文,没有时间就再说了