从数据库加载菜单及子菜单主要使用递归的方法,具体实现可看代码

首先封装一个菜单pojo

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; public String getId() {
return id;
} public void setId(String id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getParentId() {
return parentId;
} public void setParentId(String parentId) {
this.parentId = parentId;
} public String getUrl() {
return url;
} public void setUrl(String url) {
this.url = url;
} public String getIcon() {
return icon;
} public void setIcon(String icon) {
this.icon = icon;
} public int getOrder() {
return order;
} public void setOrder(int order) {
this.order = order;
} public List<Menu> getChildMenus() {
return childMenus;
} public void setChildMenus(List<Menu> childMenus) {
this.childMenus = childMenus;
}
}

  然后写dao接口

package com.xfma.dao;

import com.xfma.pojo.Menu;

import java.util.List;

public interface MenuMapper {
/**
* 查找用户的菜单
* @return
*/
public List<Menu> queryMenuList();
}

  接着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.xfma.dao.MenuMapper" > <select id="queryMenuList" resultType="com.xfma.pojo.Menu">
SELECT
id,`name`,parent_id as parentId,url,icon,`order`
FROM
jrbac_menu ORDER BY `order` ASC
</select> </mapper>

  接下来是service接口

package com.xfma.service;

import com.xfma.pojo.Menu;

import java.util.List;

public interface IMenuService {
public List<Menu> listMenu();
}

  service实现类

package com.xfma.service.impl;

import com.xfma.dao.MenuMapper;
import com.xfma.pojo.Menu;
import com.xfma.service.IMenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils; import java.util.ArrayList;
import java.util.List; @Service
public class MenuService implements IMenuService { @Autowired
private MenuMapper menuMapper; public List<Menu> listMenu() {
List<Menu> rootMenus = menuMapper.queryMenuList();
List<Menu> list = getMenuList(rootMenus);
return list;
} /**
* 找出一级菜单和二级菜单
* @param rootMenus
* @return
*/
private List<Menu> getMenuList(List<Menu> rootMenus){
List<Menu> list = new ArrayList<Menu>();
// 先找到所有的一级菜单
for (int i=0;i<rootMenus.size();i++){
Menu menu = rootMenus.get(i);
//一级菜单 没有父节点
if (StringUtils.isEmpty(menu.getParentId())){
list.add(menu);
}
} //查找二级菜单
/**
* 利用递归找出所有子菜单
*/
for (Menu menu: list) {
menu.setChildMenus(getChild(menu.getId(),rootMenus));
} return list; } /**
* 找出子菜单
* @param id
* @param rootMenu
* @return
*/
private List<Menu> getChild(String id, List<Menu> rootMenu) {
// 子菜单
List<Menu> childList = new ArrayList<Menu>(); for (Menu menu : rootMenu) {
// 遍历所有节点,将父菜单id与传过来的id比较
if (!StringUtils.isEmpty(menu.getParentId())) {
if (menu.getParentId().equals(id)) {
childList.add(menu);
}
}
} // 把子菜单的子菜单再循环一遍
for (Menu menu : childList) {// 没有url子菜单还有子菜单
if (StringUtils.isEmpty(menu.getUrl())) {
// 递归
menu.setChildMenus(getChild(menu.getId(), rootMenu));
}
} // 递归退出条件
if (childList.size() == 0) {
return null;
} return childList;
}
}

  返回的结果是已经封装好的各个菜单和子菜单,只需前台遍历就可以了。

下面附上SQL脚本:

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');

  

Java从数据库读取页面树形菜单的更多相关文章

  1. java从数据库读取菜单,递归生成菜单树

    首先看一下菜单的样子 根据这个样子我们定义菜单类 public class Menu { // 菜单id private String id; // 菜单名称 private String name; ...

  2. ExtJS4.2 根据数据库记录构建树形菜单

    背景:最近用ExtJS4.2做一个系统,需要在前端展示资源菜单,为树形结构,该树形结构是从数据库动态加载的. ExtJS的树形结构大致有两种情况: 1.静态树形结构,此处不多说,看API就能简单明白: ...

  3. java 传入list集合 返回树形菜单,for循环遍历

    public List<SysPermissionVO> getTreeMenu(List<SysPermissionVO> list,SysPermissionVO sysP ...

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

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

  5. easyui-从数据库读取创建无极菜单

    easyui-tree基础必须知道这个如下: 树控件使用<ul>元素定义.标签能够定义分支和子节点.节点都定义在<ul>列表内的<li>元素中.以下显示的元素将被用 ...

  6. Java递归应用:输出树形菜单

    转自:https://blog.csdn.net/zhangzeyuaaa/article/details/24574769

  7. java树形菜单实现

    java树形菜单实现 公司表: 部门表: 实体类: public class Node { private Integer companyId;//公司id private String compan ...

  8. java构建树形菜单递归工具类

    1.设计菜单实体 import java.util.List; public class Menu { //菜单id private Long id; //父节点id private Long par ...

  9. easyui实现树形菜单Tab功能、layout布局

    一:常见三种前端ui框架 在初学者入门的状态下,我们常见的前端框架有三种且都有自己的官方网站: 1.easyui:官方网站(http://www.jeasyui.net/) 基于jquery的用户页面 ...

随机推荐

  1. [topcoder]SRM 647 DIV 2

    第一题,送分题. 第二题, #include <vector> #include <algorithm> #include <map> #include <q ...

  2. replace into 浅析

    转载自:http://blog.itpub.net/22664653/viewspace-1669734/ http://blog.itpub.net/22664653/viewspace-16701 ...

  3. Kruskal算法求最小生成树(POJ2485)

    题目链接:http://poj.org/problem?id=2485 #include <iostream> #include <stdio.h> #include < ...

  4. TeamCity实战(2):NuGet服务器

    如果有在内网架设NuGet服务器的需要,比如说公司要求所有开发人员的开发机与外网隔离,但是项目开发又必须要通过NuGet获取开发包的情况. 打开选项其实很简单,但是打开之后怎么样更新开发包要复杂些了. ...

  5. lasagne保存网络参数

    # Optionally, you could now dump the network weights to a file like this: # np.savez('model.npz', *l ...

  6. bootstrap中模态框、模态框的属性

    工作中有需要用到模态框的可以看看 <div class="modal fade" id="userModal" tabindex="-1&quo ...

  7. Spring初始化Bean或销毁Bean前执行操作的方式

    如果想在Spring初始化后,或者销毁前做某些操作,常用的设定方式有三种: 第一种:通过 在xml中定义init-method 和 destory-method方法 推荐使用,缺陷是只能在XML中使用 ...

  8. jquery 添加和删除节点

    // 增加一个三和一节点 function addPanel() { // var newPanel = $('.my-panel').clone(true) var newPanel = $(&qu ...

  9. 我是如何根据豆瓣api来理解Restful API设计的

    1.什么是REST REST全称是Representational State Transfer,表述状态转移的意思.它是在Roy Fielding博士论文首次提出.REST本身没有创造新的技术.组件 ...

  10. 关于 ReactNative 环境搭建之 error: invalid developer directory '/Library/Developer/CommandLineTools' - RN

    简要说明,此次尝试安装 ReactNative 时当前 MacPro 版本为 10.13.6.Xcode 版本为 Version 9.4.1 (9F2000),按照官方的完整原生环境搭建流程一步步执行 ...