层级1级2级3级,map存储数据库查到的结果Map<parentId,List(ItemCat)>

从数据库获取到列表数据(层级), 把下一层的数据放到上一层的children中

优化 : 查询速度/时间
实现逻辑 : 查询一次得到所有数据, 把数据封装到map集合中, 通过集合直接获取  

为什么使用map ? 
	> 把父级的子级放到children中, 把子级封装到list集合中赋值给父级, 
	> 父级 子级的联系是父级的id是子级parentId 
	> parentId对应的是子级的集合, 就是父级id对应它的子级的list集合
	> map中key-parentid  value-List
	
Map<parentId,List<ItemCat>>
	key                 value
	0级的id             1级集合         (只有一个key)
	1级的id             每一个1id(2级的parentId)对应一个2级集合list      有多个key
	2级的id             每一个2id(3级的parentId)对应一个3级集合list      有多个key
	
map逻辑 : 
	key不能重复, value的list增加,  遇到相同的key直接放到list中
	不存在: 存储该key, 创建list集合作为value,并把自己放到里面
	存在:   获得相同key的value, 把自己追加进去
	(这里的存在/不存在指的是 parentId, 相同父级存一个list)

获取级别逻辑 : 
	1: 
		map.get(0) 就是12:
		得到1, 通过1级的id(2级的parentId), 获取2级的集合,2级的集合添加到1级的children中
		itemCatOne.setChildren(map.get(itemCatOne.getId()));
		最终返回的是 1级中children封装2级的list
	3:
		执行2级的,得到1级中children有2级
		遍历结果, 得到的是1, 获取1级的children, 得到的是2级的list
		遍历2级list, 根据2级的id获取3级的list,3级list放到2级的children中
		最终返回的是 1级中children封装2级的list,2级中children封装3级list

service业务:
	    public Map<Integer,List<ItemCat>> getItemCatListMap(){
        // map用于根据parentId封装数据
        HashMap<Integer, List<ItemCat>> map = new HashMap<>();
        // 获取数据库中的数据 ItemCat的List
        List<ItemCat> itemCatsListAll = itemCatDao.selectList(null);
        // 遍历list  封装到map中
        for (ItemCat itemCat : itemCatsListAll) {
            // 得到parentId
            Integer parentId = itemCat.getParentId();
            if (map.containsKey(parentId)){
                // 不是第一次(已经存在)   1.得到相同key的value   2.把自己放到value中的list中
                List<ItemCat> listTwo = map.get(parentId);
                listTwo.add(itemCat);
            }else{
                // 第一次    1.封装List   2.把自己放到list中   3.把list放到map中
                List<ItemCat> listFirst = new ArrayList<>();
                listFirst.add(itemCat);
                map.put(parentId,listFirst);
            }
        }
        // 返回map集合
        return map;
    }
    // getItemCatList
    @Overried
    public List<ItemCat> getItemCatListTwo(Integer level){
        long startTime = System.currentTimeMillis();
        List<ItemCat> list = new ArrayList<>();
        
        // 封装方法 getItemCatListMap  --获取所有数据, 并把数据按parentId封装到map集合中
        Map<Integer, List<ItemCat>> itemCatListMap = getItemCatListMap();

        // 判断level  要获取哪一级
        // level=1, 1级目录 就是parentId为0, map中的key=0
        if (level==1){   list = itemCatListMap.get(0);   }
        // level=2, 在level=3时, 也要使用, 
        // 所以放在这个方法 getItemCatListTwo 返回封装了2级的1级list
        if (level==2){   list = getItemCatListTwo(itemCatListMap);   }
        // level=3, 执行2, 得到带有2的1, 遍历list, getChildren得到2级, 遍历2级, 
        // 把3级放到2级children中
        if (level==3){
            // 获取 children中封装了2级的1级list
            List<ItemCat> itemCatListOne = getItemCatListTwo(itemCatListMap);
            for (ItemCat itemCatOne : itemCatListOne) {
                // 通过1级的children的到 2级list
                List<ItemCat> itemCatListTwo = itemCatOne.getChildren();
                		// bug 问题: 如果没有2级列表,不执行后面的,  结束本轮循环
                		if (itemCatListTwo==null||itemCatListTwo.size()==0){
		                    continue;
		                }
                for (ItemCat itemCatTwo : itemCatListTwo) {
                    // 1.根据2级id,   2.获取3级list,   3.把3级list放到2级children中
                    itemCatTwo.setChildren(itemCatListMap.get(itemCatTwo.getId()));
                }
            }
            list = itemCatListOne;
        }
        long endTime = System.currentTimeMillis();
        System.out.println("Map封装数据,耗时: "+(endTime-startTime)+" 耗时");
        return list;
    }
    public List<ItemCat> getItemCatListTwo(Map<Integer,List<ItemCat>> map){
        List<ItemCat> listOne = map.get(0);
        for (ItemCat itemCatOne : listOne) {
            // 1.根据1级id,   2.获取2级list,   3.把2级list放到1级children中
            itemCatOne.setChildren(map.get(itemCatOne.getId()));
        }
        return listOne;
    }
    

连接数据库方式:

        @Override
        public List<ItemCat> getItemCatList(Integer level) {
            long startTime = System.currentTimeMillis();
            
            QueryWrapper<ItemCat> qw = new QueryWrapper<>();
            qw.eq("parent_id",0);
            List<ItemCat> itemCats = itemCatDao.selectList(qw);

            if (level!=1){
                for (ItemCat itemCat1 : itemCats) {
                    qw.clear();
                    qw.eq("parent_id",itemCat1.getId());
                    List<ItemCat> itemCats2 = itemCatDao.selectList(qw);
                    itemCat1.setChildren(itemCats2);

                    if (level!=2){
                        for (ItemCat itemCat2 : itemCats2) {
                            qw.clear();
                            qw.eq("parent_id",itemCat2.getId());
                            List<ItemCat> itemCats3 = itemCatDao.selectList(qw);
                            itemCat2.setChildren(itemCats3);
                        }
                    }
                }
            }
            
            long endTime = System.currentTimeMillis();
            System.out.println("mp : "+(endTime-startTime));
            return itemCats;
        }

for循环:
for循环会形成 笛卡尔积 速度慢

    @Override
    public List<ItemCat> findAllLevelOne() {
        long startTime = System.currentTimeMillis();
        List<ItemCat> itemCats = itemCatDao.selectList(null);
        List<ItemCat> oneLevel = new ArrayList<>();
        // 一级
        for (ItemCat one : itemCats) {
            List<ItemCat> oneChildren = new ArrayList<>();
            if (one.getLevel()==1){
                Integer idOne = one.getId();
                // 二级
                for (ItemCat two : itemCats) {
                    List<ItemCat> twoChildren = new ArrayList<>();
                    if (two.getLevel()==2){
                        Integer idTwo = two.getId();
                        Integer parentIdTwo = two.getParentId();
                        // 二级的添加到一级children
                        if (idOne == parentIdTwo){
                            oneChildren.add(two);
                        }
                        // 三级
                        for (ItemCat three : itemCats) {
                            if (three.getLevel()==3){
                                Integer parentIdThree = three.getParentId();
                                // 三级添加到 二级 children
                                if (idTwo == parentIdThree){
                                    twoChildren.add(three);
                                }
                            }
                        }
                        two.setChildren(twoChildren);
                    }
                }
                one.setChildren(oneChildren);
                oneLevel.add(one);
            }
        }
        long endTime = System.currentTimeMillis();
        System.out.println("for : "+(endTime-startTime));     //  1958
        return oneLevel;
    }

已经知道树形结构数据展示的后端代码为controller层@RequestMapping("/list") public R list() { List<TbUnit> list = unitService.listAll(); return R.ok().put("data", list);}service层的lmpl /** * 查询所有的unit数据, 并返回树形结构 * * @return */ @Override public List<TbUnit> listAll() { // 查询所有数据 List<TbUnit> list = this.list(); // 建立map映射(id->index) HashMap<Integer, Integer> map = new HashMap<>(); for (int index = 0; index < list.size(); index++) { Integer id = list.get(index).getId(); map.put(id, index); } // ... for (int i = 0; i < list.size(); i++) { TbUnit node = list.get(i); Integer pid = node.getPid(); // 有父亲 if (pid != null) { // 找到pid的父亲, 并把当前节点(node)添加到父亲节点的children里面 Integer indexParent = map.get(pid); // 获取父亲节点 TbUnit parent = list.get(indexParent); if (parent.getChildren() == null) { parent.setChildren(new ArrayList<>()); } // 向父亲节点的children字段添加当前node parent.getChildren().add(node); } } // 过滤出一节点 List<TbUnit> ans = list.stream().filter(e -> e.getPid() == null).collect(Collectors.toList()); return ans; }数据库表为DROP TABLE IF EXISTS `tb_unit`; CREATE TABLE `tb_unit` ( `id` int NOT NULL AUTO_INCREMENT COMMENT &#39;主键&#39;, `unit` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_croatian_ci NULL DEFAULT NULL COMMENT &#39;单位名称&#39;, `pid` int NULL DEFAULT NULL COMMENT &#39;父id&#39;, PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 9 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_croatian_ci COMMENT = &#39;用户所属单位设置表&#39; ROW_FORMAT = Dynamic;SET FOREIGN_KEY_CHECKS = 1;如何改写为spring boot3结合mybatis的项目后端代码,已经知道我自己的项目只有mapper层(CategoryMapper),service层(没有impl,直接在 CategoryService里写代码)controller(CategoryController)层,mapper.xml(CatergoryMapper.xml)数据库表为CREATE TABLE `category` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT &#39;课程分类id&#39;, `title` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT &#39;课程分类标题&#39;, `parent_id` int(11) DEFAULT NULL COMMENT &#39;父ID&#39;, `sort` int(10) unsigned DEFAULT &#39;0&#39; COMMENT &#39;排序字段&#39;, PRIMARY KEY (`id`) ) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT=&#39;课程分类&#39;;给出改写后的全部代码,要求可以运行
最新发布
03-22
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值