前言
tips
基本上每个项目都会用到树结构的数据,比如说动态菜单,组织结构,省市县等数据,因此封装树结构的处理很重要。
提示:以下是本篇文章正文内容,下面案例可供参考
1.准备好测试数据
2.创建对应实体与交互体
@Data
@TableName("test_node")
public class NodePO {
private Integer id;
private String name;
private Integer parentId;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
@ApiModel("节点交互VO")
public class NodeVO {
@ApiModelProperty("id")
private Integer id;
@ApiModelProperty("节点名字")
private String name;
@ApiModelProperty("父级id")
private Integer parentId;
@ApiModelProperty("子节点集合")
private List<NodeVO> children;
}
3.service层核心代码
@Service
public class NodeService {
@Autowired
NodeMapper nodeMapper;
public List<NodeVO> getNodeList() {
QueryWrapper<NodePO> queryWrapper = new QueryWrapper<>();
List<NodePO> nodePOS = nodeMapper.selectList(queryWrapper);
// 对查询出来的节点进行操作,先查出父节点,在递归查询父节点下面的子节点
return getChildren(0,nodePOS);
}
/**
* 根据父节点查询下面的直接子节点,再给直接子节点递归查询子节点,递归出口就是遍历完了,依旧没有子节点,就向上回溯
*
* @param pid
* @param nodes
* @return
*/
private List<NodeVO> getChildren(Integer pid, List<NodePO> nodes) {
ArrayList<NodeVO> childNodes = new ArrayList<>();
nodes.stream().map(nodePO -> {
NodeVO nodeVO = new NodeVO();
BeanUtils.copyProperties(nodePO, nodeVO);
return nodeVO;
}).forEach(nodeVO -> {
if(Objects.equals(nodeVO.getParentId(),pid)){
childNodes.add(nodeVO);
// 在给该子节点递归查找并设置子节点,将子节点的id作为父节点id去查询子节点集合
nodeVO.setChildren(getChildren(nodeVO.getId(),nodes));
}
});
return childNodes;
}
}
4.测试响应结果数据
总结
该方式效率比较低,后面会继续优化