多级分类(树形结构)数据解决方案

  |   0 评论   |   0 浏览

多级分类(树形结构)数据解决方案

1.需求说明

在日常开发中多级分类、多级栏目、数据字典等需求,是我们经常会遇到的问题。需求的难点在于表结构的设计以及数据结构数据的封装。

  • 需求图解

image-20221105220935892

2.表结构设计

表字段说明

1.这里以家居分类为例,当然在实际开发中表字段会有一些差异。但只要是多级的树形结构我们通常都会根据parant_id去区分。

2.cat_level表示所属级别,返回给前端方便前端对父级和子级进行增删的判断,比如只允许1、2级别的分类进行添加操作;只允许最内层的分类进行删除操作。

3.is_show是否展示改分类、也可以用is_delete做逻辑删除来实现。

4.sort排序,如果由对分类排序需求可以根据改字段进行排序,如果没有则默认根据添加的先后顺序进行排序。

CREATE TABLE `commodity_category` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `name` char(50) NOT NULL COMMENT '名称',
  `parent_id` bigint(20) NOT NULL COMMENT '父分类 id',
  `cat_level` int(11) NOT NULL COMMENT '层级',
  `is_show` tinyint(4) NOT NULL COMMENT '0 不显示,1 显示]',
  `sort` int(11) NOT NULL COMMENT '排序',
  `icon` char(255) NOT NULL COMMENT '图标',
  `pro_unit` char(50) NOT NULL COMMENT '统计单位',
  `pro_count` int(11) NOT NULL COMMENT '商品数量',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=653 DEFAULT CHARSET=utf8mb4 COMMENT='商品分类表';

image-20221105221527201

3.代码实现

1.分类树形结构接口

CategoryController

/**
 * 分类树形结构
 * @return
 */
@RequestMapping("/list/tree")
public R listTree() {
    List<CategoryEntity> entities = categoryService.listTree();
    return R.ok().put("data", entities);
}

2.核心业务实现

实现思路

1.查找出所有的一级分类集合

2.遍历一级分类,查找子级分类并利用递归查找子级下的子级分类逐级设置数据

3.返回带有层级关系的数据

image-20221105223719574

CategoryService

//返回所有分类及其子分类(带有层级关系,树形结构)
List<CategoryEntity> listTree();

CategoryServiceImpl

/**
 * 返回所有分类及其子分类(带有层级关系,树形结构)
 *
 * @return
 */
@Override
public List<CategoryEntity> listTree() {
    //1.查询出所有数据
    List<CategoryEntity> entities = baseMapper.selectList(null);
    //2.组装成树形结构
    List<CategoryEntity> categoryTree = entities.stream().filter(categoryEntity -> {
        //2.1进行过滤,返回一级分类
        return categoryEntity.getParentId() == 0;
    }).map(category -> {
        //2.2进行map映射操作,给每个分类设置对应的子分类(这个过程会使用到递归)
        category.setChildrenCategories(getChildrenCategories(category, entities));
        return category;
    }).sorted((category1, category2) ->
            (category1.getSort() == null ? 0 : category1.getSort()) - (category2.getSort() == null ? 0 : category2.getSort()))
            .collect(Collectors.toList());
    //3.返回带有层级关系的数据
    return categoryTree;
}

/**
 * 该方法的任务就是将root下的所有分类的层级关系组织好(有多少级就处理多少级),并返回
 * 1.得到分类下的所有子分类
 * 2.递归操作得到子分类下的子分类
 * 3.进行排序返回
 * 4.递归结束的方向是朝着,找到root这个一级分类下的所有子分类去结束的
 * @param root
 * @param all
 * @return
 */
private List<CategoryEntity> getChildrenCategories(CategoryEntity root, List<CategoryEntity> all) {
    List<CategoryEntity> childrenCategories = all.stream()
            .filter(categoryEntity -> categoryEntity.getParentId().equals(root.getId()))
            .map(categoryEntity -> {
                categoryEntity.setChildrenCategories(getChildrenCategories(categoryEntity, all));
                return categoryEntity;
            }).sorted(Comparator.comparingInt(category -> (category.getSort() == null ? 0 : category.getSort())))
            .collect(Collectors.toList());
    return childrenCategories;
}

3.持久层采用mybatisplus实现,也可以使用写sql语句进行实现


标题:多级分类(树形结构)数据解决方案
作者:llp
地址:https://llinp.cn/articles/2022/11/06/1667721088743.html