评论A ├── 评论B,回复A │ └── 评论C,回复B └── 评论D,回复A人员系统
public class Multistage { public Multistage(Integer id,Integer parentId,String message) { this.id = id; this.parentId = parentId; this.message = message; } /** * id */ private Integer id; /** * 父类id */ private Integer parentId; /** * 名称 */ private String name; // 省略get、set }数据表和上面的实体类似。
public class ViewMultistage { /** * id */ private Integer id; /** * 父类id */ private Integer parentId; /** * 名称 */ private String name; /** * 子集 */ private List<ViewMultistage> children = new ArrayList<>(); }上面的几个例子,评论、部门、以及商品的分类,都是需要展示所有数据,所以需要从数据库获取所有数据,再使用代码归类。针对这种多级、不确定层级数量的,一般都使用递归方法获取。从数据库获取到列表数据,使用递归方式转换:
// 数据库获取数据 List<Multistage> multistageList = "select * from t_xxxx"; // 堆代码 duidaima.com // 树形结果 ViewMultistage root = new ViewMultistage(); // 添加首节点 root.setId(-1); // 递归添加 add(root,multistageList); // 结果 List<ViewMultistage> viewMultistageList = root.getChildren(); System.out.println(viewMultistageList); // 递归添加数据 private void add(ViewMultistage rootViewMultistage, List<Multistage> multistageList) { for (Multistage multistage : multistageList) { if (rootViewMultistage.getId().equals(multistage.getParentId())) { ViewMultistage viewMultistage = new ViewMultistage(); BeanUtils.copyProperties(multistage, viewMultistage); rootViewMultistage.getChildren().add(viewMultistage); add(viewMultistage, multistageList); } } }简略解释一下代码:
Integer id = 3; Set<Integer> idSet = new HashSet<>(); idSet.add(id); for (ViewMultistage multistage : viewMultistageList) { Integer parentId = multistage.getParentId(); if (idSet.contains(parentId)) { idSet.add(multistage.getId()); } }通过某个 id 就可以筛选部门以及子部门的集合,然后通过部门 id 的集合就能获取到人员信息。但是如果只是获取一小部门的子集,却要获取全部数据,有点浪费查询资源。可以在数据库中刷选好数据,通过数据库递归获取数据。
WITH RECURSIVE family_tree AS ( -- 基础查询:从给定的一级 id 开始 SELECT id, parent_id FROM parents WHERE id = 1 -- 替换为你要查询的一级 id UNION ALL -- 递归查询:查找子节点 SELECT p.id, p.parent_id FROM parents p INNER JOIN family_tree ft ON p.parent_id = ft.id ) select tu.* from family_tree ft left join t_user tu on tu.dept_id = ft.id分析with recursive用法:
上面的 family_tree 就类似通过父部门获取到所有的子部门,使用用户表关联,就能获取所有部门以及子部门的用户信息。
如果是评论的数据,就需要存储评论的等级,先分页获取一级的评论,再通过一级评论获取下级评论。