一般后台导航菜单为两层的树形结构,一般查询的思路是递归或者双重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; }