This is the 17th day of my participation in the November Gwen Challenge. Check out the event details: The last Gwen Challenge 2021

The complete example code addresses are as follows: github.com/Dr-Water/sp…

First, the origin of the problem of permission tree

  1. In the development, it is inevitable to encounter a multi-level menu structure tree, or multi-level department structure tree, or multi-level province, district and county structure, data structure is similar to the following JSON data:
[{"id": "1"."name": "Main Menu 1"."pid": "0"."menuChildren": [{"id": "4"."name": "Submenu 1.1"."pid": "1"."menuChildren": [{"id": "6"."name": "Submenu 1.1.1"."pid": "4"."menuChildren": []}, {"id": "9"."name": "Submenu 1.1.2"."pid": "4"."menuChildren": []}]}, {"id": "5"."name": "Submenu 1.2"."pid": "1"."menuChildren": []}]}, {"id": "2"."name": "Main Menu 2"."pid": "0"."menuChildren": [{"id": "Seven"."name": "Submenu 2.1"."pid": "2"."menuChildren": []}, {"id": "8"."name": "Submenu 2.2"."pid": "2"."menuChildren": []}]}, {"id": "3"."name": "Main Menu 3"."pid": "0"."menuChildren": []}]Copy the code

Second, solutions

Current solutions mainly include the following two solutions:

  • Scheme 1: The back end returns all the required data to the front end in a big list, and the front end performs operations to make the data into a tree structure
  • There are two solutions to this problem: the backend makes the data into a hierarchical structure before the backend returns it
    • Method 1: Secondary data query, in the Java program to build the tree structure
    • Method two: the first time to query the highest level of data, and then repeatedly query the database to query the sub-data

Since the front-end level of the blogger is limited, only the back-end implementation method can be used at present, and the cost of each query database is relatively high, so this paper uses method 1 of scheme 2 for verification

Implementation steps

Take the structure tree of a menu

  1. Prepare basic data for the mysql database

2. Java entity classes

@Data
@NoArgsConstructor
public class Menu implements Serializable {

    private String  id;
    private String name;
    private String pid;
    private List<Menu> menuChildren;
}
Copy the code
  1. Java dao layer
@Mapper
public interface MenuDao {

    /** * Query subclass menu * by parent class ID@param pid
     * @return* /
     List<Menu> selectByPid(Integer pid);

    /** * query all menus *@return* /
     List<Menu> selectAll(a);

    /** * query the menu except the first level menu *@return* /
     List<Menu> selectAllNotBase(a);
}
Copy the code
  1. Mapper file

      
<! DOCTYPEmapper
        PUBLIC "- / / mybatis.org//DTD Mapper / 3.0 / EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ratel.shiro.dao.MenuDao">


    <select id="selectByPid" resultType="com.ratel.shiro.entity.Menu">
        SELECT * FROM menu WHERE  pid=#{pid}
    </select>

    <select id="selectAll" resultType="com.ratel.shiro.entity.Menu">
        SELECT * FROM menu
    </select>

    <select id="selectAllNotBase" resultType="com.ratel.shiro.entity.Menu">SELECT * FROM menu where pid! = 0</select>
</mapper>
Copy the code
  1. Controller layer (since it is query operation, and no complex operation, lazy not write service layer)
@RestController
@RequestMapping("mymenu")
public class MenuController {

    @Autowired
    private MenuDao menuDao;


    @RequestMapping("/getMenuTree")
    public List<Menu> getMenuTree(a){
        List<Menu> menusBase = menuDao.selectByPid(0);
        List<Menu> menuLNotBase = menuDao.selectAllNotBase();
        for (Menu menu : menusBase) {
            List<Menu> menus = iterateMenus(menuLNotBase, menu.getId());
            menu.setMenuChildren(menus);
        }
        return  menusBase;
    }


    /** * multilevel menu query method *@paramMenuVoList is a collection of menus that does not contain the highest level menus *@paramPid Parent class ID *@return* /
    public List<Menu> iterateMenus(List<Menu> menuVoList,String pid){
        List<Menu> result = new ArrayList<Menu>();
        for (Menu menu : menuVoList) {
            // Get the menu id
            String menuid = menu.getId();
            // Get the parent id of the menu
            String parentid = menu.getPid();
            if(StringUtils.isNotBlank(parentid)){
                if(parentid.equals(pid)){
                    // Recursively queries submenus of the current submenuList<Menu> iterateMenu = iterateMenus(menuVoList,menuid); menu.setMenuChildren(iterateMenu); result.add(menu); }}}returnresult; }}Copy the code
  1. The launcher tests with Postman:

The json data returned is as follows:

[{"id": "1"."name": "Main Menu 1"."pid": "0"."menuChildren": [{"id": "4"."name": "Submenu 1.1"."pid": "1"."menuChildren": [{"id": "6"."name": "Submenu 1.1.1"."pid": "4"."menuChildren": []}, {"id": "9"."name": "Submenu 1.1.2"."pid": "4"."menuChildren": []}]}, {"id": "5"."name": "Submenu 1.2"."pid": "1"."menuChildren": []}]}, {"id": "2"."name": "Main Menu 2"."pid": "0"."menuChildren": [{"id": "Seven"."name": "Submenu 2.1"."pid": "2"."menuChildren": []}, {"id": "8"."name": "Submenu 2.2"."pid": "2"."menuChildren": []}]}, {"id": "3"."name": "Main Menu 3"."pid": "0"."menuChildren": []}]Copy the code

Reference links: Java recursive processing permission management menu tree or classification once done permission tree traversal ——– permission tree background traversal general solution (Java background) user permissions multi-level menu traversal method Java with recursive implementation of the ball upper and lower levels (involves the removal of the upper level) Java recursion gets a summary of the Java recursion algorithm for all child nodes below a parent node