当前位置:网站首页>How to write elegant secondary classification for enterprise development [small case of meituan]

How to write elegant secondary classification for enterprise development [small case of meituan]

2022-06-11 15:23:00 Evader1997

demand

This paper explains the idea of assembling tree structure through a case
 Insert picture description here

The requirement is to return the page data for front-end display , You can see that the left column is the primary classification of meituan , Click the corresponding primary classification, and the corresponding secondary classification will be displayed on the right . But in addition to the classification names, there are many more numbers in the figure , This will be the most difficult point in this case . If it is solved, it will be a cycle , If it is not solved well, it is a two-layer cycle .

Table structure and data

Case I created two tables , Namely shop( Shop list ) Follow type( Classification table ). stay type There is a field in shop_type_id It corresponds to the classification in the classification table id.
 Insert picture description here
 Insert picture description here

analysis

Through the analysis of demand graph and table structure , The data returned in the first reaction is a tree structure . The so-called tree structure is Java In general, it is List package List, We can't understand Java8 How to write new features :

  1. Query all the first level classifications in the classification table
  2. Query all the secondary classifications in the classification table
  3. Traverse the first level classification set
  4. Traverse the second level classification set , adopt Secondary classification id With his father id Make connections Put the secondary classification under the primary classification
  5. The data is assembled , The result is returned to the front end

Optimize the pre writing method

public List<FirstTypeInfo> selectTypeListTwo() {
    
        //  Query all primary and secondary classifications 
        List<Type> firstLevelList = typeMapper.selectByLevel(1);
        List<Type> secondLevelList = typeMapper.selectByLevel(2);

        //  Create a return result set collection 
        List<FirstTypeInfo> firstTypeInfoList = new ArrayList<>();
        //  First level classification cycle 
        for (Type firstType : firstLevelList) {
    
            FirstTypeInfo firstTypeInfo = new FirstTypeInfo();
            List<SecondTypeInfo> secondTypeInfoList = new ArrayList<>();
            //  Count the total quantity of the first level classification 
            int firstShopCount = 0;
            //  Second level classification cycle 
            for (Type secondType : secondLevelList) {
    
                if (secondType.getTypeParentsId().equals(firstType.getTypeId())) {
    
                    SecondTypeInfo secondTypeInfo = new SecondTypeInfo();
                    secondTypeInfo.setSecondTypeId(secondType.getTypeId());
                    secondTypeInfo.setSecondTypeName(secondType.getTypeName());
                    //  Query the number of stores in the current secondary category 
                    int secondShopCount = shopMapper.selectSecondShopCount(secondType.getTypeId());
                    secondTypeInfo.setSecondTypeCount(secondShopCount);
                    secondTypeInfo.setSecondTypeParentsId(secondType.getTypeParentsId());
                    secondTypeInfoList.add(secondTypeInfo);
                    firstShopCount += secondShopCount;
                }
            }
            firstTypeInfo.setFirstTypeId(firstType.getTypeId());
            firstTypeInfo.setFirstTypeName(firstType.getTypeName());
            firstTypeInfo.setFirstTypeCount(firstShopCount);
            firstTypeInfo.setSecondTypeInfoList(secondTypeInfoList);
            firstTypeInfoList.add(firstTypeInfo);
        }
        //  Return result set 
        return firstTypeInfoList;
    }

The problem is

  1. The first problem is the use of query statements in the loop selectSecondShopCount(), this signify I will execute as many query statements as there are categories , It is also executed in a loop ! This is a Seriously affect performance Of , When the amount of data is small and the single project will not make mistakes , Just take a long time . But under the microservice Architecture , There is a call relationship between services , There are requirements for the interface time , Too long request time will cause response timeout , Call failed .
  2. The second problem is that there are two layers of loops , In fact, we can do overall treatment for the secondary classification , From the figure, we can see that the data of secondary classification is complete Can pass group by Statement to find out , adopt Stream Stream to plug the collection , The standard of stoppage selection is the third in the analysis 4 spot
  3. The third is an optimization point , We don't just have the number of secondary classifications , There is also the number of primary classifications , The number of secondary classifications can count But there is no way to classify at the first level , It is the sum of two classes , At first, I defined a variable outside the loop firstShopCount, This variable is used to calculate the sum of the first level classification

The above expression is not used Java 8 New characteristics ,Stream Flow and Lambda expression , The other is that it is not flexible to use SQL knowledge

How to optimize

  1. utilize group by Group according to the required fields , Get the set of secondary classification ( Omit the second layer of circulation )
  2. Collection operation use Stream flow , coordination Lambda Simplify the code
  3. The sum of the first level classification is still used Stream, By parent id Make contact , Reduce the number of interactions with the database

Final code

The main logic

public List<FirstTypeInfo> selectTypeList() {
    
        //  Query all categories ( Including primary classification and secondary classification )
        List<Type> typeList = typeMapper.selectAll();
        //  Filter out all the primary classifications 
        List<Type> firstTypes = typeList.stream()
                .filter(type -> "1".equals(type.getLevel().toString()))
                .collect(Collectors.toList());

        //  Batch query of store information and quantity (sql See the next code block )
        List<SecondTypeInfo> secondTypeInfoList = shopMapper.selectShopInfoAndCount();

        //  Create a new one List Store the assembled data 
        List<FirstTypeInfo> firstTypeInfoList = new ArrayList<>();
        //  Assembly data 
        for (Type firstType : firstTypes) {
    
            FirstTypeInfo firstTypeInfo = new FirstTypeInfo();
            firstTypeInfo.setFirstTypeId(firstType.getTypeId());
            firstTypeInfo.setFirstTypeName(firstType.getTypeName());

            //  Judge whether there is a secondary classification under the primary classification , If not, the first level classification will not be displayed 
            int sum = secondTypeInfoList.stream()
                    .filter(secondTypeInfo -> firstType.getTypeId().equals(secondTypeInfo.getSecondTypeParentsId()))
                    .mapToInt(SecondTypeInfo::getSecondTypeCount)
                    .sum();
            if (sum == 0) {
    
                continue;
            }
            firstTypeInfo.setFirstTypeCount(sum);

            //  Secondary list 
            List<SecondTypeInfo> secondTypeInfos = secondTypeInfoList.stream()
                    .filter(secondTypeInfo -> firstType.getTypeId().equals(secondTypeInfo.getSecondTypeParentsId()))
                    .collect(Collectors.toList());
            firstTypeInfo.setSecondTypeInfoList(secondTypeInfos);

            firstTypeInfoList.add(firstTypeInfo);
        }
        return firstTypeInfoList;
    }

The key SQL

<select id="selectShopInfoAndCount" resultType="com.evader.generator.model.SecondTypeInfo">
    select t.type_id as secondTypeId, t.type_name as secondTypeName, t.type_parents_id as secondTypeParentsId,count(s.shop_type_id) as secondTypeCount
    from type t
    left join shop s
    on t.type_id = s.shop_type_id
    group by t.type_id, t.type_name, t.type_parents_id
  </select>

result

 Insert picture description here

Leave a problem

In fact, meituan has more than one type of merchants , In this case , The type of store is an array , How to make statistics at this time ? Those who are interested can think about it .

原网站

版权声明
本文为[Evader1997]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/162/202206111518260412.html