数据库中树形结构数据的处理

在一些场景中,我们经常会遇到前端发来的多级目录类型的请求,我将对这个问题给出一个合理的操作方法。

如图,前端页面此时需要获取一个分类列表。

 其大致结构如下

             

 所以我们的接口设计也应该配合其格式,我们在表结构的设计上采用树形思想,将其数据id作为节点坐标,并且用一个字段记录其父节点坐标。

                     

对于表的映射,我采用了继承关系,以便实现多级存储。表CourseCategory用来提供数据模板,表CourseCategoryTreeDto继承CourseCategory用来实现数据的真正存储,其中定义了其自身类型的集合用来存储其子分类。

                                            

 至于将表中的数据映射到表的过程,有sql递归、自连接等方式,大家可以自行选择。

因为我们不考虑总根节点的情况,所以我们的返回值用该是由多个一级分类组成的集合,即List<CourseCategoryTreeDto>。

我们对数据进行构建的过程,这里我采用了递归的方式。

第一个方法中,我对数据库中的数据进行获取,并调用所创建的递归方法。

递归方法具体的实现思路如下:

我设置了两个参数,第一个参数为当前节点父节点的坐标,第二个参数为获取的数据列表。

因为我们从头结点进行遍历,所以默认初始坐标为“1”,当遍历到的数据其父节点等于当前父节点时,则首先对其子节点进行构建,在这个过程中我们应当考虑第一次构建子节点时属性还未实例化,所以要进行非空判断。接下来进行递归操作,将参数一设置为当前遍历到的节点的坐标,参数二依然是数据列表,并将其结果赋值给当前节点的List<CourseCategoryTreeDto>,但是同时还要注意最后一级子节点的属性的实例化问题,我们应该为其设置为null,防止传回空数组。最后将每个一级分类放入提前定义好的列表中。将结果进行返回。

 @Autowired
    private CourseCategoryMapper courseCategoryMapper;

    @Override
    public List<CourseCategoryTreeDto> queryTreeNodes(String id) {
        List<CourseCategoryTreeDto> courseCategoryTreeDtos = courseCategoryMapper.selectTreeNodes(id);
        return addNodes(id, courseCategoryTreeDtos);
    }

    public List<CourseCategoryTreeDto> addNodes(String id, List<CourseCategoryTreeDto> courseCategoryTreeDtos) {
        List<CourseCategoryTreeDto> result = new ArrayList<>();
        //对数据进行遍历
        for (CourseCategoryTreeDto courseCategoryTreeDto : courseCategoryTreeDtos) {
            //当数据的父节点等于根节点时,先对其子节点进行递归构建
            if (courseCategoryTreeDto.getParentid().equals(id)) {
                //防止空指针
                if (courseCategoryTreeDto.getChildrenTreeNodes() == null) {
                    courseCategoryTreeDto.setChildrenTreeNodes(new ArrayList<>());
                }
                //递归构建当前数据的子节点,并赋值给父节点
                List<CourseCategoryTreeDto> courseCategoryTreeDtos1 = addNodes(courseCategoryTreeDto.getId(), courseCategoryTreeDtos);
                //若子节点未进行填充,则设置为NULL
                if (courseCategoryTreeDtos1.isEmpty()) {
                    courseCategoryTreeDtos1 = null;
                }
                courseCategoryTreeDto.setChildrenTreeNodes(courseCategoryTreeDtos1);
                //将所有的二级节点(父节点)放入集合中
                result.add(courseCategoryTreeDto);
            }
        }
        return result;
    }

我采用的递归思想就是首先对每个节点进行其子节点的构建,但是其中可能会有时间复杂度的差异,这取决于数据列表是否有序,所以这里我对数据查询时采用了递归的方法。

最后前端接收到的结果图如下

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值