一、结构树查询
1、概述
平时开发业务逻辑中经常遇到查询所有父类及子类、三级分类、所有菜单以及子菜单、所有部门以及子部门类似的需求,如何使用递归构造这样的树数据呢?
2、数据库
类似业务分类、菜单、部门类似的需求数据库表只需一张即可,如下(没有父分类 则parentid=0)
主要是分类id以及当前分类所属的父分类parent_id。
3、实体类设计
public class Category { private IntegercatId; private String name; private Integer parentCid; //用来存储子分类list private List<Category> children; }
省去了get以及set方法
4、分析代码实现步骤
//获取树型列表 public List<Category> listWithTree() { //首先查询所有分类的一级父类id列表 List<Category> categoryList = categoryDao.selectList(); List<Category> categoryListWithTree = categoryList.stream().filter(category-> category.getParentCid()==0 ).map((menu)->{ menu.setChildren(getChildrens(menu,categoryList)); return menu; }).sorted((menu1,menu2)->{//按照分类id排序 return menu1.getCatId()-menu2.getCatId(); }).collect(Collectors.toList()); return categoryListWithTree; } //递归查询当前分类的所有子分类 public List<Category> getChildrens(Category root,List<Category> all){ List<Category> childrens = all.stream().filter(category -> { return category.getParentCid()==root.getCatId(); }).map((category)->{ category.setChildren(getChildrens(category,all)); return category; }).sorted((menu1,menu2)->{//按照分类id排序 return (menu1.getCatId()==null?0:menu1.getCatId())-(menu2.getCatId()==null?0:menu2.getCatId()); }).collect(Collectors.toList()); return childrens; }
测试
二、查询某个父类的所有子父类集合(非树结构)
基础类
//省略get set public class Menu { private Integer id; private String name; private Integer pid; } public List<Menu> getChildren(Integer pid, List<Menu> all, List<Menu> children) { for (Menu d : all) { //遍历出父id等于参数的id,add进子节点集合 if (d.getPid().equals(pid)) { //递归遍历下一级 getChildren(d.getId(), all, children); children.add(d); } } return children; } public void test(){ List<Menu > children = new ArrayList<>(); List<Menu > all = new ArrayList<>(); children = getChildren(0, all, children); for (Menu d : children) { System.out.println(d.getName()); } }