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


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

    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='商品分类表';
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    image-20221105221527201

    3.代码实现

    1.分类树形结构接口

    CategoryController

    /**
     * 分类树形结构
     * @return
     */
    @RequestMapping("/list/tree")
    public R listTree() {
        List<CategoryEntity> entities = categoryService.listTree();
        return R.ok().put("data", entities);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    2.核心业务实现

    实现思路

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

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

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

    image-20221105223719574

    CategoryService

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

    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() == 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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

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

  • 相关阅读:
    计算每组的前 N 名
    数据结构从入门到精通——栈
    「Java 数据结构和算法」:图文详解---中缀表达式转后缀表达式。
    129-Vue中表单修饰符
    深入浅出了解MYSQL8特性注入是什么
    laravel 模型Filter类型判断筛选
    LeetCode //C - 46. Permutations
    【Python大数据笔记_day07_hive中的分区表、分桶表以及一些特殊类型】
    <C++>入门新概念
    查找算法之二分查找
  • 原文地址:https://blog.csdn.net/qq_44981526/article/details/127710429