zoukankan      html  css  js  c++  java
  • Java 数据库树形查询生成菜单结构

    Java 数据库树形查询

    JAVA从数据库读取菜单,递归生成菜单树。

    定义菜单类

    public class Menu {
        // 菜单id
        private String id;
        // 菜单名称
        private String name;
        // 父菜单id
        private String parentId;
        // 菜单url
        private String url;
        // 菜单图标
        private String icon;
        // 菜单顺序
        private int order;
        // 子菜单
        private List<Menu> childMenus;
        // ... 省去getter和setter方法以及toString方法
    }
    

    根据这个类定义数据库并且插入我们的菜单数据。
    创建数据库

    DROP TABLE IF EXISTS `jrbac_menu`;
    CREATE TABLE `jrbac_menu` (
      `id` varchar(32) NOT NULL COMMENT '主键id,uuid32位',
      `name` varchar(64) NOT NULL COMMENT '登录用户名',
      `parent_id` varchar(32) DEFAULT NULL COMMENT '父菜单id',
      `url` varchar(64) DEFAULT NULL COMMENT '访问地址',
      `icon` varchar(32) DEFAULT NULL COMMENT '菜单图标',
      `order` tinyint(4) DEFAULT '0' COMMENT '菜单顺序',
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='菜单表';
    

    插入模拟数据

    INSERT INTO `jrbac_menu` VALUES ('1', 'Forms', null, 'forms.html', 'fa fa-edit', '0');
    INSERT INTO `jrbac_menu` VALUES ('2', 'UI Elements', null, '', 'fa fa-wrench', '1');
    INSERT INTO `jrbac_menu` VALUES ('3', 'Buttons', '2', 'buttons.html', '', '0');
    INSERT INTO `jrbac_menu` VALUES ('4', 'Icons', '2', 'icons.html', null, '1');
    INSERT INTO `jrbac_menu` VALUES ('5', 'Multi-Level Dropdown', '', '', 'fa fa-sitemap', '2');
    INSERT INTO `jrbac_menu` VALUES ('6', 'Second Level Item', '5', 'second.html', null, '0');
    INSERT INTO `jrbac_menu` VALUES ('7', 'Third Level', '5', null, '', '1');
    INSERT INTO `jrbac_menu` VALUES ('8', 'Third Level Item', '7', 'third.html', null, '0');
    

    测试方法

    private final Gson gson = new GsonBuilder().disableHtmlEscaping().create();
    @Test
    public void testQueryMenuList() {
        // 原始的数据
        List<Menu> rootMenu = menuDao.queryMenuList(null);
    
        // 查看结果
        for (Menu menu : rootMenu) {
            System.out.println(menu);
        }
        // 最后的结果
        List<Menu> menuList = new ArrayList<Menu>();
        // 先找到所有的一级菜单
        for (int i = 0; i < rootMenu.size(); i++) {
            // 一级菜单没有parentId
            if (StringUtils.isBlank(rootMenu.get(i).getParentId())) {
                menuList.add(rootMenu.get(i));
            }
        }
        // 为一级菜单设置子菜单,getChild是递归调用的
        for (Menu menu : menuList) {
            menu.setChildMenus(getChild(menu.getId(), rootMenu));
        }
        Map<String,Object> jsonMap = new HashMap<>();
        jsonMap.put("menu", menuList);
        System.out.println(gson.toJson(jsonMap));
    
    }
    

    递归查找子菜单

    /**
     * 递归查找子菜单
     * 
     * @param id
     *            当前菜单id
     * @param rootMenu
     *            要查找的列表
     * @return
     */
    private List<Menu> getChild(String id, List<Menu> rootMenu) {
        // 子菜单
        List<Menu> childList = new ArrayList<>();
        for (Menu menu : rootMenu) {
            // 遍历所有节点,将父菜单id与传过来的id比较
            if (StringUtils.isNotBlank(menu.getParentId())) {
                if (menu.getParentId().equals(id)) {
                    childList.add(menu);
                }
            }
        }
        // 把子菜单的子菜单再循环一遍
        for (Menu menu : childList) {// 没有url子菜单还有子菜单
            if (StringUtils.isBlank(menu.getUrl())) {
                // 递归
                menu.setChildMenus(getChild(menu.getId(), rootMenu));
            }
        } // 递归退出条件
        if (childList.size() == 0) {
            return null;
        }
        return childList;
    }
    

    meuDao

    package com.jrbac.dao;
    
    import java.util.List;
    
    import com.jrbac.entity.LoginUser;
    import com.jrbac.entity.Menu;
    
    public interface MenuDao {
    
        /**
         * 查找用户的菜单
         * @param loginUser
         * @return
         */
        public List<Menu> queryMenuList(LoginUser loginUser);
    }
    

    mybatis

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.jrbac.dao.MenuDao">
        <select id="queryMenuList" resultType="Menu">
            SELECT 
                id,`name`,parent_id,url,icon,`order`
            FROM 
                jrbac_menu ORDER BY `order` ASC
        </select>
    </mapper>
    

    测试程序的运行结果,对输出的json进行个格式化后的对比。

  • 相关阅读:
    MySQL的排序方式
    Hibernate中查询优化策略
    kafka实现SASL_PLAINTEXT权限认证·集成springboot篇
    kafka实现SASL_PLAINTEXT权限认证·服务器篇
    SpringMvc服务端实现跨域请求解决方案
    maven打包日志输出优化-去掉泛型与过时的警告
    SpringMVC之控制器的单例和多例管理
    springmvc中的controller是单例的
    com.caucho.hessian.io.HessianProtocolException: is unknown code 解决方案
    浅谈大型web系统架构
  • 原文地址:https://www.cnblogs.com/wjw1014/p/11750834.html
Copyright © 2011-2022 走看看