美文网首页
商品分类查询业务代码优化

商品分类查询业务代码优化

作者: 情安 | 来源:发表于2021-08-13 10:22 被阅读0次

1.现有代码存在的问题

@Override
    public List<ItemCat> findItemCatList(Integer level) {
        //性能问题:!!!!!
        long startTime = System.currentTimeMillis();
        //1.查询一级商品分类信息
        QueryWrapper<ItemCat> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("parent_id", 0);
        List<ItemCat> oneList = itemCatMapper.selectList(queryWrapper);
        //2.查询二级商品分类信息  遍历一级集合
        for(ItemCat oneItemCat : oneList){
            queryWrapper.clear();   //清空条件
            queryWrapper.eq("parent_id", oneItemCat.getId());
            List<ItemCat> twoList = itemCatMapper.selectList(queryWrapper);
            //3.查询三级商品分类信息  遍历
            for(ItemCat twoItemCat : twoList){
                queryWrapper.clear();
                queryWrapper.eq("parent_id", twoItemCat.getId());
                List<ItemCat> threeList = itemCatMapper.selectList(queryWrapper);
                //将三级封装给二级
                twoItemCat.setChildren(threeList);
            }
            //3.将二级记录封装给一级
            oneItemCat.setChildren(twoList);
        }
        //记录程序的结束时间
        long endTime = System.currentTimeMillis();
        System.out.println("查询耗时:"+(endTime - startTime)+"毫秒");
        return oneList;
    }

问题说明: 如果经过2次for循环, 链接数据库的次数将会很多, 直接影响查询的效率.
优化: 尽可能的降低查询的次数,同时满足用户需求.

2.优化策略

数据结构: Map<K,V> map
Key=“父级ID” Value=List<当前父级的子级>
用法: 如果想要获取任意父级的子级 map.get(父级的ID)
用法说明: Value 只有父级的子级信息,没有嵌套结构
Map<父级ID,List<ItemCat{id=xx,name=xx,children=null}>>


原理图

2.1封装Map实现完整代码

   /**
     * 1.封装Map集合   Map<Key=父级ID,value=List<ItemCat对象>>
     * 2.说明:  将所有的数据库的父子关系,进行封装.(没有嵌套!!!!)
     * 3.优势:  只查询一次数据库,就可以完成父子关系的封装.
        策略:
     *      1. key不存在, 准备一个新List集合,将自己当作第一个元素追加
     *      2. key存在,  获取原有list集合,将自己追加.
     *
     */
    public Map<Integer,List<ItemCat>> initMap(){
        //Map中包含了所有的父子级关系.
        Map<Integer,List<ItemCat>> map = new HashMap<>();
        //1.查询item_cat表中的所有的记录(1/2/3级菜单)
        List<ItemCat> itemCatList = itemCatMapper.selectList(null);
        //2.实现数据的封装
        for(ItemCat itemCat : itemCatList){
            int key = itemCat.getParentId();
            if(map.containsKey(key)){ //存在
                List<ItemCat> list = map.get(key);
                //将自己追加到其中
                list.add(itemCat);
            }else{  //不存在: 准备List集合,将自己作为第一个元素封装
                List<ItemCat> list = new ArrayList<>();
                list.add(itemCat);
                map.put(key,list);
            }
        }
        //将封装的数据进行返回.
        return map;
    }


    /**
     * level 1 只查询一级商品分类
     *       2 查询一级/二级  嵌套封装
     *       3 查询一级/二级/三级   嵌套封装
     * @param level
     * @return
     */
    @Override
    public List<ItemCat> findItemCatList(Integer level) {
        long startTime = System.currentTimeMillis();
        //Map集合里边封装的是所有的父子级关系.
        Map<Integer,List<ItemCat>> map = initMap();
        if(level == 1){ //只获取1级菜单. parent_id = 0
            return map.get(0);
        }
        //用户查询1/2级商品分类信息
        if(level == 2){
            return getLevel2List(map);
        }

        //如果程序执行到这里,则说明用户查询的是1-2-3级菜单
        List<ItemCat> list = getLevel3List(map);
        long endTime = System.currentTimeMillis();
        System.out.println("耗时:"+(endTime-startTime)+"毫秒");
        return list;
    }

    public List<ItemCat> getLevel3List(Map<Integer, List<ItemCat>> map) {
        //1.先查询1-2级
        List<ItemCat> oneList = getLevel2List(map);

        //2.遍历集合
        for(ItemCat oneItemCat : oneList){
            //获取二级集合信息
            List<ItemCat> twoList = oneItemCat.getChildren();
            if(twoList == null || twoList.size() ==0){
                //当前一级菜单没有二级元素.结束本次循环,开始下一次!!!
                continue;
            }
            //该元素有二级,应该查询三级.
            for(ItemCat twoItemCat : twoList){
                List<ItemCat> threeList = map.get(twoItemCat.getId());
                twoItemCat.setChildren(threeList);
            }
        }
        return oneList;
    }

    //查询一级和二级信息
    public List<ItemCat> getLevel2List(Map<Integer, List<ItemCat>> map) {
        //思路: 先查询一级,之后循环遍历,再次封装2级
        //1.获取一级
        List<ItemCat> oneList = map.get(0);
        for(ItemCat oneItemCat : oneList){
            //2.如何根据一级查询二级? 通过Map集合获取
            List<ItemCat> twoList = map.get(oneItemCat.getId());
            //3.实现了一级二级的封装
            oneItemCat.setChildren(twoList);
        }
        return oneList;
    }

3.优化后结果对比

优化前: 优化后:

相关文章

  • 商品分类查询业务代码优化

    1.现有代码存在的问题 问题说明: 如果经过2次for循环, 链接数据库的次数将会很多, 直接影响查询的效率.优化...

  • 商品管理案例——案例准备

    一、案例的概述 1、案例实现的功能 分类管理  查询分类  添加分类  删除分类  修改分类 商品管理  查询商品...

  • 秒杀思路思考

    1.表设计 2. 核心业务: 3. 基本实现 4. 优化点: ***************** 1. 查询商品库...

  • 三级分类级联查询

    商品分类下有三级 ​​​ 查询结果: ​​​

  • SQL优化器原理 - 查询优化器综述

    本文主要是对数据库查询优化器的一个综述,包括: 查询优化器定义、分类 查询优化器执行过程 CBO框架Calcite...

  • [es]ES数据查询调优2

    查询语句优化 查询语句优化的内容包括:查询范围,单次查询数量等。 根据实际业务需求去规划查询范围,查询越少的字段越...

  • Mysql 子查询

    -- 查询分类名称为手机数码的所有商品1.查询分类名为手机数码的IDSELECT cid FROM categor...

  • Spring Cloud—三、使用Spring Cloud实现微

    业务:1.商品微服务:通过商品id查询商品的服务。2.订单微服务:创建订单时,通过调用商品的微服务进行查询商品数据...

  • mysql性能优化-慢查询分析、优化索引和配置

    mysql性能优化-慢查询分析、优化索引和配置 分类:Mysql/postgreSQL 目录 一、优化概述 二、查...

  • Mysql子查询子分类

    业务中,常常碰到例如菜单,商品等多级分类的业务,而大多数程序员都会在程序的循环中去写子类的查询,数据量大、分级多的...

网友评论

      本文标题:商品分类查询业务代码优化

      本文链接:https://www.haomeiwen.com/subject/lljdbltx.html