菜单数据库
我们要把它搞成树状菜单,对应前端的json格式,结果应该类似这样
我们接下来就要把数据库·的数据拼接成树状菜单:首先来个菜单对象
public class TreeNode {
private Integer id;
private Integer pid;
private String title;
private String href;
private Boolean spread;
//子菜单
private List<TreeNode> children = new ArrayList<TreeNode>();
}
我们通过数据库查出来的菜单应该是数据库有几个,查出来就有几个;然后我们要递归拼接子菜单
public static List<TreeNode> build(List<TreeNode> originalTreeNodes, Integer pid) {
//对于递归调用来说是定义一个保存子菜单的list
//因为是new的,每次递归都会生成新的,来保存当前查询的子菜单,返回给上一层递归调用
//对调用这个方法的用户来说,返回的就是结果
List<TreeNode> treeNodes= new ArrayList<>();
//循环
for (TreeNode o : originalTreeNodes) {
//找到父节点为pid的菜单对象
if (o.getPid().equals(pid)) {
//添加到list,相当于把子菜单存起来
treeNodes.add(o);
//再把当前的节点当做父节点参数传过去,递归,找到父节点为当前菜单对象
List<TreeNode> childMenus = build(originalTreeNodes, o.getId());
//设置子菜单
o.setChildren(childMenus);
}
}
//返回菜单,对于for循环里调用build(),返回的结果就是子菜单
return treeNodes;
}
测试:
@Test
void build() {
List<TreeNode> treeNodes= new ArrayList<>();
TreeNode t1=new TreeNode(2,1,"基础管理",false);
TreeNode t2=new TreeNode(3,1,"进货管理",false);
TreeNode t11=new TreeNode(4,2,"客户管理",false);
TreeNode t12=new TreeNode(5,2,"商品管理",false);
TreeNode t21=new TreeNode(6,3,"商品进货",false);
TreeNode t22=new TreeNode(7,3,"商品退货查询",false);
treeNodes.add(t1);
treeNodes.add(t2);
treeNodes.add(t11);
treeNodes.add(t12);
treeNodes.add(t21);
treeNodes.add(t22);
List<TreeNode> build = TreeNodeBuilder.build(treeNodes, 1);
}
递归就要想着这是棵树,会比较好理解,从左至右,从上到下查,调用bulid(treeNodes, 1) ,先从左边第一棵id:2的叶子节点开始查,是pid为1了,加到一个新的集合(pid1List)里,再向下查,父节点(pid)为自己(id:2)的叶子节点,查到id:6的叶子结点的pid为2,加到新的集合(pid2List)里,再向下查发现没有,回到id:6的叶子结点这层栈,这里保存着pid2List集合,然后在向上,还没查完,继续向右下查 ,查到id:7的叶子结点的pid为2,加到新的集合(pid2List)里,这时pid2List有俩了,返回(向上),发现都查完了,传pid2List回去。id:2的叶子节点这层获取到pid2List,然后就设置子节点为pid2List,反复如此。
参数pid,就是可以直接想获取哪层菜单都行。
对以上测试案例的递归调用图
上面原文件下载 https://download.csdn.net/download/Fire_Sky_Ho/13454713