zoukankan      html  css  js  c++  java
  • 商品分类(递归子目录)接口开发笔记

    商品分类(递归子目录)接口开发笔记

    开发如下接口:

    1.所有类目

    GET /categories

    request

    无需登录

    response

    success

    {
        "status": 0,
        "data": [{
            "id": 100001,
            "parentId": 0,
            "name": "家用电器",
            "sortOrder": 1,
            "subCategories": [{
                "id": 100006,
                "parentId": 100001,
                "name": "冰箱",
                "sortOrder": 2,
                "subCategories": [{
                    "id": 100040,
                    "parentId": 100006,
                    "name": "进口冰箱",
                    "sortOrder": 1,
                    "subCategories": []
                }]
            },  {
            "id": 100005,
            "parentId": 0,
            "name": "酒水饮料",
            "sortOrder": 1,
            "subCategories": [{
                "id": 100026,
                "parentId": 100005,
                "name": "白酒",
                "sortOrder": 1,
                "subCategories": []
            }, {
                "id": 100027,
                "parentId": 100005,
                "name": "红酒",
                "sortOrder": 1,
                "subCategories": []
            }]
        }]
    }
    

    数据库表:

    /*
     Navicat Premium Data Transfer
    
     Source Server         : 本地数据库
     Source Server Type    : MySQL
     Source Server Version : 50726
     Source Host           : localhost:3306
     Source Schema         : mimall
    
     Target Server Type    : MySQL
     Target Server Version : 50726
     File Encoding         : 65001
    
     Date: 27/03/2020 22:10:31
    */
    
    SET NAMES utf8mb4;
    SET FOREIGN_KEY_CHECKS = 0;
    
    -- ----------------------------
    -- Table structure for mall_category
    -- ----------------------------
    DROP TABLE IF EXISTS `mall_category`;
    CREATE TABLE `mall_category`  (
      `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '类别Id',
      `parent_id` int(11) NULL DEFAULT NULL COMMENT '父类别id当id=0时说明是根节点,一级类别',
      `name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '类别名称',
      `status` tinyint(1) NULL DEFAULT 1 COMMENT '类别状态1-正常,2-已废弃',
      `sort_order` int(4) NOT NULL DEFAULT 1 COMMENT '数字越大,排序优先级越高',
      `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
      `update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间',
      PRIMARY KEY (`id`) USING BTREE
    ) ENGINE = InnoDB AUTO_INCREMENT = 100052 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
    
    -- ----------------------------
    -- Records of mall_category
    -- ----------------------------
    INSERT INTO `mall_category` VALUES (100001, 0, '家用电器', 1, 1, '2000-03-25 16:46:00', '2000-03-25 16:46:00');
    INSERT INTO `mall_category` VALUES (100002, 0, '数码3C', 1, 2, '2000-03-25 16:46:21', '2000-03-25 16:46:21');
    INSERT INTO `mall_category` VALUES (100003, 0, '服装箱包', 1, 1, '2000-03-25 16:49:53', '2000-03-25 16:49:53');
    INSERT INTO `mall_category` VALUES (100004, 0, '食品生鲜', 1, 1, '2000-03-25 16:50:19', '2000-03-25 16:50:19');
    INSERT INTO `mall_category` VALUES (100005, 0, '酒水饮料', 1, 1, '2000-03-25 16:50:29', '2000-03-25 16:50:29');
    INSERT INTO `mall_category` VALUES (100006, 100001, '冰箱', 1, 1, '2000-03-25 16:52:15', '2000-03-25 16:52:15');
    INSERT INTO `mall_category` VALUES (100007, 100001, '电视', 1, 2, '2000-03-25 16:52:26', '2000-03-25 16:52:26');
    INSERT INTO `mall_category` VALUES (100008, 100001, '洗衣机', 1, 1, '2000-03-25 16:52:39', '2000-03-25 16:52:39');
    INSERT INTO `mall_category` VALUES (100009, 100001, '空调', 1, 1, '2000-03-25 16:52:45', '2000-03-25 16:52:45');
    INSERT INTO `mall_category` VALUES (100010, 100001, '电热水器', 1, 1, '2000-03-25 16:52:54', '2000-03-25 16:52:54');
    INSERT INTO `mall_category` VALUES (100011, 100002, '电脑', 1, 1, '2000-03-25 16:53:18', '2000-03-25 16:53:18');
    INSERT INTO `mall_category` VALUES (100012, 100002, '手机', 1, 1, '2000-03-25 16:53:27', '2000-03-25 16:53:27');
    INSERT INTO `mall_category` VALUES (100013, 100002, '平板电脑', 1, 1, '2000-03-25 16:53:35', '2000-03-25 16:53:35');
    INSERT INTO `mall_category` VALUES (100014, 100002, '数码相机', 1, 1, '2000-03-25 16:53:56', '2000-03-25 16:53:56');
    INSERT INTO `mall_category` VALUES (100015, 100002, '3C配件', 1, 1, '2000-03-25 16:54:07', '2000-03-25 16:54:07');
    INSERT INTO `mall_category` VALUES (100016, 100003, '女装', 1, 1, '2000-03-25 16:54:44', '2000-03-25 16:54:44');
    INSERT INTO `mall_category` VALUES (100017, 100003, '帽子', 1, 1, '2000-03-25 16:54:51', '2000-03-25 16:54:51');
    INSERT INTO `mall_category` VALUES (100018, 100003, '旅行箱', 1, 1, '2000-03-25 16:55:02', '2000-03-25 16:55:02');
    INSERT INTO `mall_category` VALUES (100019, 100003, '手提包', 1, 1, '2000-03-25 16:55:09', '2000-03-25 16:55:09');
    INSERT INTO `mall_category` VALUES (100020, 100003, '保暖内衣', 1, 1, '2000-03-25 16:55:18', '2000-03-25 16:55:18');
    INSERT INTO `mall_category` VALUES (100021, 100004, '零食', 1, 1, '2000-03-25 16:55:30', '2000-03-25 16:55:30');
    INSERT INTO `mall_category` VALUES (100022, 100004, '生鲜', 1, 1, '2000-03-25 16:55:37', '2000-03-25 16:55:37');
    INSERT INTO `mall_category` VALUES (100023, 100004, '半成品菜', 1, 1, '2000-03-25 16:55:47', '2000-03-25 16:55:47');
    INSERT INTO `mall_category` VALUES (100024, 100004, '速冻食品', 1, 1, '2000-03-25 16:55:56', '2000-03-25 16:55:56');
    INSERT INTO `mall_category` VALUES (100025, 100004, '进口食品', 1, 1, '2000-03-25 16:56:06', '2000-03-25 16:56:06');
    INSERT INTO `mall_category` VALUES (100026, 100005, '白酒', 1, 1, '2000-03-25 16:56:22', '2000-03-25 16:56:22');
    INSERT INTO `mall_category` VALUES (100027, 100005, '红酒', 1, 1, '2000-03-25 16:56:30', '2000-03-25 16:56:30');
    INSERT INTO `mall_category` VALUES (100028, 100005, '饮料', 1, 1, '2000-03-25 16:56:37', '2000-03-25 16:56:37');
    INSERT INTO `mall_category` VALUES (100029, 100005, '调制鸡尾酒', 1, 1, '2000-03-25 16:56:45', '2000-03-25 16:56:45');
    INSERT INTO `mall_category` VALUES (100030, 100005, '进口洋酒', 1, 1, '2000-03-25 16:57:05', '2000-03-25 16:57:05');
    INSERT INTO `mall_category` VALUES (100040, 100006, '进口冰箱', 1, 1, '2020-03-27 20:02:27', '2020-03-27 20:02:29');
    INSERT INTO `mall_category` VALUES (100050, 100040, '进口德国冰箱', 1, 1, '2020-03-27 21:27:19', '2020-03-27 21:27:22');
    
    SET FOREIGN_KEY_CHECKS = 1;
    
    

    开发思路分析:
    1、先查出一级目录 —> 查其子目录,一直查到的是null (从外到内)

    2、查出目录 - >查父目录,一直查到parent_id=0(从内到外)

    本次笔记使用思路一,先查询一级目录,在便利查询子目录,没有子目录为止

    分析数据可得最外层使用ResponseVo即可,data 为Category类的部分成员变量,故可新建一个CategoryVo类设置相关变量,由于子Category中有Category,所以需要添加List subCategories 以实现递归嵌套。

    CategoryVo类:

    package cn.blogsx.mimall.vo;
    
    import lombok.Data;
    
    import java.util.List;
    
    /**
     * @author Alex
     * @create 2020-03-27 20:09
     **/
    @Data
    public class CategoryVo {
        private Integer id;
    
        private Integer parentId;
    
        private String name;
    
        private Integer sortOrder;
    
        private List<CategoryVo> subCategories; //如此设计即可实现递归
    
    }
    

    service层:

    package cn.blogsx.mimall.service;
    
    import cn.blogsx.mimall.vo.CategoryVo;
    import cn.blogsx.mimall.vo.ResponseVo;
    
    import java.util.List;
    
    public interface ICategoryService {
    
    
        ResponseVo<List<CategoryVo>> selectAll();
    }
    

    实现类:

    package cn.blogsx.mimall.service.impl;
    
    import cn.blogsx.mimall.dao.CategoryMapper;
    import cn.blogsx.mimall.pojo.Category;
    import cn.blogsx.mimall.service.ICategoryService;
    import cn.blogsx.mimall.vo.CategoryVo;
    import cn.blogsx.mimall.vo.ResponseVo;
    import org.springframework.beans.BeanUtils;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import java.util.ArrayList;
    import java.util.Comparator;
    import java.util.List;
    import java.util.stream.Collectors;
    
    import static cn.blogsx.mimall.consts.MiMallConst.ROOT_PARENT_ID;
    
    /**
     * @author Alex
     * @create 2020-03-27 20:16
     **/
    @Service
    public class CategoryServiceImpl implements ICategoryService {
        @Autowired
        private CategoryMapper categoryMapper;
    
        /**
         * 耗时:http(请求api) > 磁盘 > 内存
         * mysql(内网 + 磁盘)
         * @return
         */
    
        @Override
        public ResponseVo<List<CategoryVo>> selectAll() {
    //        List<CategoryVo> categoryVoList = new ArrayList<>();
    
            List<Category> categories = categoryMapper.selectAll();
            //查出parent_id=0
    //        for (Category category : categories) {
    //            if(category.getParentId().equals(ROOT_PARENT_ID)) {
    //                CategoryVo categoryVo= new CategoryVo();
    //                BeanUtils.copyProperties(category,categoryVo);
    //                categoryVoList.add(categoryVo);
    //            }
    //        } 等价于下方写法
            //lambda + stream
            List<CategoryVo> categoryVoList = categories.stream()
                    .filter(e -> e.getParentId().equals(ROOT_PARENT_ID))
                    .map(this::categoryToCategoryVo)
                    .sorted(Comparator.comparing(CategoryVo::getSortOrder).reversed())
                    .collect(Collectors.toList());
    
            //查询子目录
            findSubCategory(categoryVoList,categories);
    
            return ResponseVo.success(categoryVoList);
    
        }
        private void findSubCategory(List<CategoryVo> categoryVoList, List<Category> categories) {
            for(CategoryVo categoryVo : categoryVoList) {
                List<CategoryVo> subCategoryVoList = new ArrayList<>();
                for (Category category : categories) {
                    //如果查到内容,设置subCategory,继续往下查
                    if(categoryVo.getId().equals(category.getParentId())) {
                        CategoryVo subCategoryVo = categoryToCategoryVo(category);
                        subCategoryVoList.add(subCategoryVo);
                    }
                    subCategoryVoList.sort(Comparator.comparing(CategoryVo::getSortOrder).reversed());//降序排序
                    categoryVo.setSubCategories(subCategoryVoList);
                    //继续往下查
                    findSubCategory(subCategoryVoList,categories);
                }
            }
        }
        private CategoryVo  categoryToCategoryVo(Category category) {
            CategoryVo categoryVo= new CategoryVo();
            BeanUtils.copyProperties(category,categoryVo);
            return categoryVo;
        }
    }
    

    查询思路:由于数据库表时分类表,故数据量不会很大,应一次性将数据全部查询出来,再根据id == parentId判断是否为子分类,并递归查询,直到子分类为null,可将查询子目录封装为方法,调用自身实现递归查询。

  • 相关阅读:
    Atitit.eclise的ide特性-------abt 编译
    Atitit.eclise的ide特性-------abt 编译
    Atitit python3.0 3.3 3.5 3.6 新特性 Python2.7新特性1Python 3_x 新特性1python3.4新特性1python3.5新特性1值得关注的新特性1Python3.6新特性2  Python2.7新特性Python 2.7的新特性
    Atitit python3.0 3.3 3.5 3.6 新特性 Python2.7新特性1Python 3_x 新特性1python3.4新特性1python3.5新特性1值得关注的新特性1Pyth
    Atitit intellij idea的使用总结attilax
    Atitit.eclipse 4.3 4.4  4.5 4.6新特性
    Atitit.eclipse 4.3 4.4  4.5 4.6新特性
    Atitit.eclipse 4.3 4.4  4.5 4.6新特性
    Atitit 软件国际化原理与概论
    Atitit 软件国际化原理与概论
  • 原文地址:https://www.cnblogs.com/sxblog/p/12585767.html
Copyright © 2011-2022 走看看