商品分類查詢業(yè)務(wù)代碼優(yōu)化

1.現(xiàn)有代碼存在的問題

@Override
    public List<ItemCat> findItemCatList(Integer level) {
        //性能問題:!!!!!
        long startTime = System.currentTimeMillis();
        //1.查詢一級(jí)商品分類信息
        QueryWrapper<ItemCat> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("parent_id", 0);
        List<ItemCat> oneList = itemCatMapper.selectList(queryWrapper);
        //2.查詢二級(jí)商品分類信息  遍歷一級(jí)集合
        for(ItemCat oneItemCat : oneList){
            queryWrapper.clear();   //清空條件
            queryWrapper.eq("parent_id", oneItemCat.getId());
            List<ItemCat> twoList = itemCatMapper.selectList(queryWrapper);
            //3.查詢?nèi)?jí)商品分類信息  遍歷
            for(ItemCat twoItemCat : twoList){
                queryWrapper.clear();
                queryWrapper.eq("parent_id", twoItemCat.getId());
                List<ItemCat> threeList = itemCatMapper.selectList(queryWrapper);
                //將三級(jí)封裝給二級(jí)
                twoItemCat.setChildren(threeList);
            }
            //3.將二級(jí)記錄封裝給一級(jí)
            oneItemCat.setChildren(twoList);
        }
        //記錄程序的結(jié)束時(shí)間
        long endTime = System.currentTimeMillis();
        System.out.println("查詢耗時(shí):"+(endTime - startTime)+"毫秒");
        return oneList;
    }

問題說明: 如果經(jīng)過2次for循環(huán), 鏈接數(shù)據(jù)庫的次數(shù)將會(huì)很多, 直接影響查詢的效率.
優(yōu)化: 盡可能的降低查詢的次數(shù),同時(shí)滿足用戶需求.

2.優(yōu)化策略

數(shù)據(jù)結(jié)構(gòu): Map<K,V> map
Key=“父級(jí)ID” Value=List<當(dāng)前父級(jí)的子級(jí)>
用法: 如果想要獲取任意父級(jí)的子級(jí) map.get(父級(jí)的ID)
用法說明: Value 只有父級(jí)的子級(jí)信息,沒有嵌套結(jié)構(gòu)
Map<父級(jí)ID,List<ItemCat{id=xx,name=xx,children=null}>>


原理圖

2.1封裝Map實(shí)現(xiàn)完整代碼

   /**
     * 1.封裝Map集合   Map<Key=父級(jí)ID,value=List<ItemCat對(duì)象>>
     * 2.說明:  將所有的數(shù)據(jù)庫的父子關(guān)系,進(jìn)行封裝.(沒有嵌套!!!!)
     * 3.優(yōu)勢(shì):  只查詢一次數(shù)據(jù)庫,就可以完成父子關(guān)系的封裝.
        策略:
     *      1. key不存在, 準(zhǔn)備一個(gè)新List集合,將自己當(dāng)作第一個(gè)元素追加
     *      2. key存在,  獲取原有l(wèi)ist集合,將自己追加.
     *
     */
    public Map<Integer,List<ItemCat>> initMap(){
        //Map中包含了所有的父子級(jí)關(guān)系.
        Map<Integer,List<ItemCat>> map = new HashMap<>();
        //1.查詢item_cat表中的所有的記錄(1/2/3級(jí)菜單)
        List<ItemCat> itemCatList = itemCatMapper.selectList(null);
        //2.實(shí)現(xiàn)數(shù)據(jù)的封裝
        for(ItemCat itemCat : itemCatList){
            int key = itemCat.getParentId();
            if(map.containsKey(key)){ //存在
                List<ItemCat> list = map.get(key);
                //將自己追加到其中
                list.add(itemCat);
            }else{  //不存在: 準(zhǔn)備List集合,將自己作為第一個(gè)元素封裝
                List<ItemCat> list = new ArrayList<>();
                list.add(itemCat);
                map.put(key,list);
            }
        }
        //將封裝的數(shù)據(jù)進(jìn)行返回.
        return map;
    }


    /**
     * level 1 只查詢一級(jí)商品分類
     *       2 查詢一級(jí)/二級(jí)  嵌套封裝
     *       3 查詢一級(jí)/二級(jí)/三級(jí)   嵌套封裝
     * @param level
     * @return
     */
    @Override
    public List<ItemCat> findItemCatList(Integer level) {
        long startTime = System.currentTimeMillis();
        //Map集合里邊封裝的是所有的父子級(jí)關(guān)系.
        Map<Integer,List<ItemCat>> map = initMap();
        if(level == 1){ //只獲取1級(jí)菜單. parent_id = 0
            return map.get(0);
        }
        //用戶查詢1/2級(jí)商品分類信息
        if(level == 2){
            return getLevel2List(map);
        }

        //如果程序執(zhí)行到這里,則說明用戶查詢的是1-2-3級(jí)菜單
        List<ItemCat> list = getLevel3List(map);
        long endTime = System.currentTimeMillis();
        System.out.println("耗時(shí):"+(endTime-startTime)+"毫秒");
        return list;
    }

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

        //2.遍歷集合
        for(ItemCat oneItemCat : oneList){
            //獲取二級(jí)集合信息
            List<ItemCat> twoList = oneItemCat.getChildren();
            if(twoList == null || twoList.size() ==0){
                //當(dāng)前一級(jí)菜單沒有二級(jí)元素.結(jié)束本次循環(huán),開始下一次!!!
                continue;
            }
            //該元素有二級(jí),應(yīng)該查詢?nèi)?jí).
            for(ItemCat twoItemCat : twoList){
                List<ItemCat> threeList = map.get(twoItemCat.getId());
                twoItemCat.setChildren(threeList);
            }
        }
        return oneList;
    }

    //查詢一級(jí)和二級(jí)信息
    public List<ItemCat> getLevel2List(Map<Integer, List<ItemCat>> map) {
        //思路: 先查詢一級(jí),之后循環(huán)遍歷,再次封裝2級(jí)
        //1.獲取一級(jí)
        List<ItemCat> oneList = map.get(0);
        for(ItemCat oneItemCat : oneList){
            //2.如何根據(jù)一級(jí)查詢二級(jí)? 通過Map集合獲取
            List<ItemCat> twoList = map.get(oneItemCat.getId());
            //3.實(shí)現(xiàn)了一級(jí)二級(jí)的封裝
            oneItemCat.setChildren(twoList);
        }
        return oneList;
    }

3.優(yōu)化后結(jié)果對(duì)比

優(yōu)化前:

優(yōu)化后:
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 網(wǎng)絡(luò) http header ,Cookie和Session的區(qū)別?分別是用于什么場(chǎng)景??jī)?yōu)缺點(diǎn)? session ...
    johnny_zhao閱讀 1,060評(píng)論 0 0
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,711評(píng)論 19 139
  • 今天是劉小愛自學(xué)Java的第143天。 感謝你的觀看,謝謝你。 學(xué)習(xí)計(jì)劃安排如下: 商品分類業(yè)務(wù)的初步實(shí)現(xiàn)。 數(shù)據(jù)...
    劉小愛閱讀 536評(píng)論 0 4
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,854評(píng)論 18 399
  • 我是黑夜里大雨紛飛的人啊 1 “又到一年六月,有人笑有人哭,有人歡樂有人憂愁,有人驚喜有人失落,有的覺得收獲滿滿有...
    陌忘宇閱讀 8,899評(píng)論 28 54

友情鏈接更多精彩內(nèi)容