查询生成二级树型结构最高效的方式

一般后台导航菜单为两层的树形结构,一般查询的思路是递归或者双重for循环,最高效的方式是通过引用类型对象的特点,引用类型存的是对象地址

递归查询核心代码:直接在sql中查询生成树 可以实现多级树 效率较低

<resultMap id="BaseResultMap" type="org.sang.bean.Menu">
    <id property="id" column="id"/>
    <result column="name" property="name"/>
    <result column="parentId" property="parentId"/>
    <collection property="children" ofType="org.sang.bean.Menu" select="org.sang.mapper.MenuMapper.getMenuByPid" column="id">
    </collection>
</resultMap>
<select id="getMenuByPid" resultMap="BaseResultMap">
    select d1.* from menu d1 where d1.`parentId`=#{pid} AND d1.enabled=true;
</select>

双重for循环查询思路:实现二层树的常规思路,算法时间复杂度O(n^2)  

public List<Menu> getMenuTree(){
     List<Menu> menus = menuDao.getAllMenu(); //查询所有菜单
     List<Menu> firstMenu = new ArrayList<>();
     for(Menu menu:menus){    //双重循环生成树
         if(menu.getParentId() == null){
               for(Menu menu2:menus){
                      if(menu2.getParentId() == menu.getId()){
                               menu.getChildren().add(menu2);
                     }
               }
               firstMenu.add(menu);
         }
    }
     return firstMenu;             
}                        

最高效的方式:通过引用类型对象的特点,引用类型存的是对象地址,算法时间复杂度2O(n)

public List<Menu> getMenuTree(){
     List<Menu> menus = menuDao.getAllMenu(); //查询所有菜单
     List<Menu> firstMenu = new ArrayList<>();
     Map<Integer, Menu> menuMap = new HashMap<>();
     for(Menu menu:menus){    
         if(menu.getParentId() == null){  //一级菜单
               firstMenu.add(menu)
         }
         menuMap.put(menu.getId, menu);
    }
     for(Menu menu:menus){    
         if(menu.getParentId() != null && menuMap.containsKey(menu.getParentId())){
               menuMap.get(menu.getParentId()).getChildren().add(menu);
         }
         menuMap.put(menu.getId, menu);
    }
     return firstMenu;             
} 
原文地址:https://www.cnblogs.com/wscw/p/15107663.html