菜单目录,地区表等经常会用tree结构的形式去展示。
1 实体
实体会表现成自我嵌套。
由id指向parentId,形成循环。
2 数据结构
可以看出 segc_id 是子节点,segc_parent_id 是父节点,根节点是 null 也有设置为0的。
1 List转tree
1.1 MybatisPlus注解 @many 实现
segc_brd_id 这只是无关紧要的状态查询条件,最主要的 many= @many 这个注解,childrer的映射之后,他能实现递归的效果。
注意的是 @many注解select上的方法名。
网上的信息也比较多。这里提供一种思路,具体实现,可以去深入研究一下,是怎么达到递归的效果的。
1.2 递归
正常来说,根据表格数据查出来都是List集合。
这里贴上代码,这里有三个变量, id 和 parentId ,根节点的值.
id指向parentId ,由底层往上开始构建tree结构,最后根节点的值判断停止迭代。这里的根节点,我们这边是null。
/** * 使用递归方法建树 */ public List<Rsegmentcategory> buildTreeByRsegmentcategory(List<Rsegmentcategory> tree) { List<Rsegmentcategory> trees = new ArrayList<>(); for (Rsegmentcategory treeNode : tree) { if (treeNode.getSegcParentId() == null) { trees.add(findChildrenByRsegmentcategory(treeNode, tree)); } } return trees; } /** * 递归查找子节点 * * @param tree * @return */ public static Rsegmentcategory findChildrenByRsegmentcategory(Rsegmentcategory treeNode, List<Rsegmentcategory> tree) { for (Rsegmentcategory it : tree) { if (treeNode.getSegcId().equals(it.getSegcParentId())) { if (treeNode.getChildren() == null) { treeNode.setChildren(new ArrayList<>()); } treeNode.getChildren().add(findChildrenByRsegmentcategory(it, tree)); } } return treeNode; }
2 tree 转 List
这里也是迭代的方法。
贴上代码
这里新建集合接收tree解析后的数据。
不断迭代,根绝children 是否为空来停止迭代。
/** * 解析树形结构 * * @param list * @return */ private static List<Rsegmentcategory> toList(List<Rsegmentcategory> list) { List<Rsegmentcategory> result = new ArrayList<>(); for (Rsegmentcategory entity : list) { result.add(entity); List<Rsegmentcategory> child = entity.getChildren(); if (child != null && child.size() > 0) { List<Rsegmentcategory> entityList = toList(child); result.addAll(entityList); } } if (result.size() > 0) { for (Rsegmentcategory entity : result) { entity.setChildren(null); } } return result; }
3 获取tree的最底层的节点
不知道是不是这样说,就是由自底层的节点一直向根节点寻找,并且记录路径。返回tree结构
差不多是画图的这个意思。
同样贴上代码
//这是获取tree结构
List<Rsegmentcategory> allTree = rsegmentcategoryDao.findAllTree(1);
// tree结构放入 map
List<Map> maps = JSONArray.parseArray(JSONUtil.toJsonStr(allTree), Map.class);
//新建一个数据接收
List<Map<String, Object>> lastChildrenList = new ArrayList<>();
//方法
this.getLastChildrens(maps, lastChildrenList, "children");
方法:
/**
* 取出最底层的Children
*
* @param data
* @param childrenList
* @param key
*/
public void getLastChildrens(List<Map> data, List<Map<String, Object>> childrenList, String key) {
if (data == null) {
return;
}
for (Map orgData : data) {
List<Rsegmentcategory> categories = (List<Rsegmentcategory>) orgData.get(key);
if (orgData.containsKey(key) && categories.size() > 0) {
getLastChildrens(JSONArray.parseArray(orgData.get(key).toString(), Map.class), childrenList, key);
} else {
childrenList.add(orgData);
}
}
}
最后将map结构在解析回来
JSONArray jsonArray = new JSONArray();
jsonArray.addAll(lastChildrenList);
//这又变成list 想转tree可以用上面的转结构方法
List<Rtagtree> list = jsonArray.toJavaList(Rtagtree.class);
学艺不精,网上缝合。以后有更好的方法在做记录。
最终效果展示
感觉挺有意思的一次需求,特此记录。