首先看一下菜单的样子

根据这个样子我们定义菜单类

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='菜单表'; -- ----------------------------
-- Records of jrbac_menu
-- ----------------------------
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;
}

menuDao.queryMenuList(null);查找的结果是一条一条的数据

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进行个格式化后的对比

java从数据库读取菜单,递归生成菜单树的更多相关文章

  1. C#递归生成HTML树,C#递归生成xml树

    C#递归生成HTML树 public StringBuilder str = new StringBuilder();   //定义一个字符串 private void get_navigation_ ...

  2. JavaScript通过父节点ID递归生成JSON树

    JavaScript通过父节点ID递归生成JSON树: · 实现思路:通过递归实现(第一次递归的时候查询出所有的父节点,然后通过当前父节点id不断地去查询所有子节点,直到递归完毕返回)   · 代码示 ...

  3. Java从数据库读取页面树形菜单

    从数据库加载菜单及子菜单主要使用递归的方法,具体实现可看代码 首先封装一个菜单pojo public class Menu { // 菜单id private String id; // 菜单名称 p ...

  4. java—将数据库读取的list转tree

    一.引言 有时候我们从数据库中读取出了一个表的数据,比如存储的是中国的省市县的ID.名称与父节点ID,读出来的数据并不是前台想要的,这个时候我们要想法处理一下都出来的list,将它变为一个树. 比如直 ...

  5. QMenu 设置菜单图标 & 生成菜单树

    效果图 源码 .h 文件 protected slots: void onMenuTriggered(QAction*); .cpp 文件 // 菜单 QMenu *pMenu = new QMenu ...

  6. Java 数据库树形查询生成菜单结构

    Java 数据库树形查询 JAVA从数据库读取菜单,递归生成菜单树. 定义菜单类 public class Menu { // 菜单id private String id; // 菜单名称 priv ...

  7. JAVA递归生成树形菜单

    递归生成一个如图的菜单,编写两个类数据模型Menu.和创建树形的MenuTree.通过以下过程实现: 1.首先从菜单数据中获取所有根节点. 2.为根节点建立次级子树并拼接上. 3.递归为子节点建立次级 ...

  8. Extjs4 treePanel异步加载菜单(后台从数据库读取)

    运行环境:springMVC+mybatis 一.建表 说明:0表示此节点为非叶子节点,即此节点还包括了子节点:1表示此节点为叶子节点,即此节点没有子节点.:关于图标iconCls是从Extjs的文件 ...

  9. Java生成菜单树(目录树)的几种方式

    本文介绍两种不同生成多级目录树的方式:1. 递归生成,2.  map+list 集合生成.最下方会附上完整代码. 生成树的基本规则:子节点的par_id等于父节点的id. 1. 实体类 import ...

随机推荐

  1. JS回调函数(理解篇)

    概述: 回调函数就是一个通过函数指针调用的函数.如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数.回调函数不是由该函数的实现方直接调用,而 ...

  2. Maven一些零散的知识点

    Maven常用命令: 1. 创建Maven的普通java项目: mvn archetype:create -DgroupId=com.yida.framework -DartifactId=hello ...

  3. Android(java)学习笔记71:Tab标签的使用

    1. 案例1---TabProject (1)首先是main.xml文件: <?xml version="1.0" encoding="utf-8"?&g ...

  4. 【HHHOJ】ZJOI2019模拟赛(十四)03.12 解题报告

    点此进入比赛 得分: \(50+5+24=79\) 排名: \(Rank\ 2\) \(Rating\):\(+79\) \(T1\):[HHHOJ197]古明地(点此看题面) 基本上全部时间都用来想 ...

  5. Codeforces 760B Frodo and pillows

    题目链接:http://codeforces.com/problemset/problem/760/B 题意:n个床位,m个枕头,第k个位置最多有多少个枕头,其中相邻之间的差<=1; 第k个位置 ...

  6. BZOJ 3233: [Ahoi2013]找硬币

    BZOJ 3233: [Ahoi2013]找硬币 标签(空格分隔): OI-BZOJ OI-DP Time Limit: 10 Sec Memory Limit: 64 MB Description ...

  7. 20145238-荆玉茗 《Java程序设计》第2次实验

    20145238 <Java程序设计>第2次实验报告 实验二 Java面向对象程序设计 一.实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建 ...

  8. Linux 启动、停止、重启tomcat工具(Shell脚本)

    1.   启动 #!/bin/bash pids=`ps -ef | grep java | grep -w tomcat | awk '{print $2}'` #pids=`ps -ef | gr ...

  9. 【洛谷P1379】八数码难题(广搜、A*)

    八数码难题 题目描述 一.广搜: 首先要考虑用什么存每一个状态 显然每个状态都用一个矩阵存是很麻烦的. 我们可以考虑将一个3*3的矩阵用一个字符串或long long 存. 每次扩展时再转化为矩阵. ...

  10. 移除input number上的spinner

    HTML 5 的表单中有着丰富的input种类,比如说input[type="number"],就可以保证用户输入数字,但是input也有一些不好的地方——带有 spinner. ...