Java构建网站多级菜单功能解决方案
DROP TABLE IF EXISTS `menu`;
CREATE TABLE `menu` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键递增',
`name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '分类名称',
`parentid` int(11) NULL DEFAULT NULL COMMENT '父节点id',
`url` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '分类链接',
`icon` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '分类图标',
`order` int(11) NULL DEFAULT NULL COMMENT '分类排序权重',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 9 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
再让我们来插入一点测试数据
INSERT INTO `menu` VALUES (1, '新闻', 0, '/www/xinwen', 'xxx', 1);
INSERT INTO `menu` VALUES (2, '每日日报', 1, '/www/meiriribao', 'xxx', 2);
INSERT INTO `menu` VALUES (3, '每日晚报', 1, '/www/zaobao', 'xxx', 1);
INSERT INTO `menu` VALUES (4, '河南日报', 2, '/www/henan', 'xxx', 2);
INSERT INTO `menu` VALUES (5, '上海日报', 2, '/www/shanghai', 'xxx', 1);
INSERT INTO `menu` VALUES (6, '南京日报', 2, '/www/nanjing', 'xxx', 3);
INSERT INTO `menu` VALUES (7, '开封日报', 4, '/www/zhoukou', 'xxx', 2);
INSERT INTO `menu` VALUES (8, '郑州日报', 4, '/www/zhenghzou', 'xxx', 3);
List<Menu> findAll();
<select id="findAll" resultMap="BaseResultMap">
select * from menu;
</select>
package com.sys.domain; import java.util.List; public class Menu implements Comparable<Menu> {
private Integer id; private String name; private Integer parentid; private String url; private String icon; private Integer order; //子菜单列表
private List<Menu> children; public List<Menu> getChildren() {
return children;
}
public void setChildren(List<Menu> children) {
this.children = children;
} public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name == null ? null : name.trim();
} public Integer getParentid() {
return parentid;
} public void setParentid(Integer parentid) {
this.parentid = parentid;
} public String getUrl() {
return url;
} public void setUrl(String url) {
this.url = url == null ? null : url.trim();
} public String getIcon() {
return icon;
} public void setIcon(String icon) {
this.icon = icon == null ? null : icon.trim();
} public Integer getOrder() {
return order;
} public void setOrder(Integer order) {
this.order = order;
} @Override
public int compareTo(Menu o) {
if (this.order != o.order) {
return this.order - o.order;
}
return 0;
}
}
实体关键点1:实体Menu实现了Comparable接口并实现了compareTo方法
这样就可以直接使用Collections.sort()方法进行List排序
实体关键点2:实体中新增一个属性List<Menu> children,用于存储返回页面的子节点
实体较介绍完了,我们就可以直接看代码啦,都加上注释了很简单
package com.sys.menutree; import com.sys.dao.MenuMapper;
import com.sys.domain.Menu;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody; import java.util.*; /**
* @Author:jimisun
* @Description:
* @Date:Created in 18:02 2018/8/8
* @Modified By:
*/
@Controller
@RequestMapping("/menu")
public class MenuController { @Autowired
private MenuMapper menuMapper; @RequestMapping(value = "/findTree", method = RequestMethod.POST)
@ResponseBody
public Map<String, Object> findTree(@RequestBody(required = false) Menu menu) {
//构建返回数据
Map<String, Object> data = new HashMap<String, Object>(); try {
//查询到的所有菜单
List<Menu> allMenu = menuMapper.findAll();
//根节点
List<Menu> rootMenu = new ArrayList<Menu>(); //根据传递的参数设置根节点
if (menu != null && menu.getId() != null) {
//父节点为传递的id为根节点
for (Menu nav : allMenu) {
if (nav.getParentid().equals(menu.getId())) {
rootMenu.add(nav);
}
}
} else {
//父节点是0的,为根节点。
for (Menu nav : allMenu) {
if (nav.getParentid().equals(0)) {
rootMenu.add(nav);
}
}
} // 根据Menu类的order排序
Collections.sort(rootMenu); //为根菜单设置子菜单,getClild是递归调用的
for (Menu nav : rootMenu) {
//获取根节点下的所有子节点 使用getChild方法
List<Menu> childList = getChild(nav.getId(), allMenu);
//给根节点设置子节点
nav.setChildren(childList);
} data.put("success", "true");
data.put("list", rootMenu);
return data;
} catch (Exception e) {
data.put("success", "false");
data.put("list", new ArrayList());
return data;
} } /**
* 递归设置栏目的子节点
*
* @param id 父节点id
* @param allMenu 节点列表
* @return
*/
private List<Menu> getChild(Integer id, List<Menu> allMenu) {
//子菜单
List<Menu> childList = new ArrayList<Menu>();
for (Menu nav : allMenu) {
// 遍历所有节点,将所有菜单的父id与传过来的根节点的id比较
//相等说明:为该根节点的子节点。
if (nav.getParentid().equals(id)) {
childList.add(nav);
}
}
//递归设置子节点
for (Menu nav : childList) {
nav.setChildren(getChild(nav.getId(), allMenu));
}
//排序
Collections.sort(childList);
//如果节点下没有子节点,返回一个空List(递归退出)
if (childList.size() == 0) {
return new ArrayList<Menu>();
}
return childList;
} }
最后我们来看一下功能演示
直接发送直接请求接口,获取的是所有分类
请求结果
{
"success": "true",
"list": [
{
"id": 5,
"name": "上海日报",
"parentid": 2,
"url": "/www/shanghai",
"icon": "xxx",
"order": 1,
"children": []
},
{
"id": 4,
"name": "河南日报",
"parentid": 2,
"url": "/www/henan",
"icon": "xxx",
"order": 2,
"children": [
{
"id": 7,
"name": "开封日报",
"parentid": 4,
"url": "/www/zhoukou",
"icon": "xxx",
"order": 2,
"children": []
},
{
"id": 8,
"name": "郑州日报",
"parentid": 4,
"url": "/www/zhenghzou",
"icon": "xxx",
"order": 3,
"children": []
}
]
},
{
"id": 6,
"name": "南京日报",
"parentid": 2,
"url": "/www/nanjing",
"icon": "xxx",
"order": 3,
"children": []
}
]
}
发送请求接口,并附带要查询的分类id
结果如下
{
"success": "true",
"list": [
{
"id": 5,
"name": "上海日报",
"parentid": 2,
"url": "/www/shanghai",
"icon": "xxx",
"order": 1,
"children": []
},
{
"id": 4,
"name": "河南日报",
"parentid": 2,
"url": "/www/henan",
"icon": "xxx",
"order": 2,
"children": [
{
"id": 7,
"name": "开封日报",
"parentid": 4,
"url": "/www/zhoukou",
"icon": "xxx",
"order": 2,
"children": []
},
{
"id": 8,
"name": "郑州日报",
"parentid": 4,
"url": "/www/zhenghzou",
"icon": "xxx",
"order": 3,
"children": []
}
]
},
{
"id": 6,
"name": "南京日报",
"parentid": 2,
"url": "/www/nanjing",
"icon": "xxx",
"order": 3,
"children": []
}
]
}
Java构建网站多级菜单功能解决方案的更多相关文章
- java实现网站paypal支付功能并且异步修改订单的状态
java实现网站paypal支付功能并且异步修改订单的状态:步骤如下 第一步:去paypal的官网https://www.paypal.com注册一个个人账号,在创建沙箱测试账号时需要用到 第二步:p ...
- java生成多级菜单树
使用java实现一个多级菜单树结构 先上数据库 ps_pid字段很重要,是父级菜单的id Menu类 Menu类要新增一个字段,用来存放子菜单 /** * 子菜单列表 */ private List& ...
- Python简单实现多级菜单
# -*- coding: utf-8 -*- # @Time : 2018-06-01 13:40 # @Author : 超人 # @Email : huxiaojiu111@gmail.com ...
- Atitit.excel导出 功能解决方案 php java C#.net版总集合.doc
Atitit.excel导出 功能解决方案 php java C#.net版总集合.docx 1.1. Excel的保存格式office2003 office2007/2010格式1 1.2. 类库选 ...
- java 24 - 7 GUI之 创建多级菜单窗体
需求: 创建多级菜单 步骤: A:创建窗体对象(并设置属性和布局) B:创建菜单栏 C:创建菜单和子菜单 D:逐步添加菜单(子菜单添加到菜单中,菜单添加到菜单栏中) E:窗体中设置菜单栏(菜单栏并不是 ...
- Vue2 实现树形菜单(多级菜单)功能模块
结构示意图 ├── index.html ├── main.js ├── router │ └── index.js # 路由配置文件 ├── components # 组件目录 │ ├── App. ...
- 网站开发---js与java实现的一些小功能
记录一下网站开发过程中的一些小功能 1.js获取当前年份: <span>Copyright © 2017-<script>document.write( new Date(). ...
- 使用Java语言开发微信公众平台(八)——自定义菜单功能
随着上一篇文章的结束,我们已经实现了所有消息的类型的回复功能.今天,我们来学习更加高大上,也更加重要的自定义菜单功能. 一.了解自定义菜单 自定义菜单是微信公众平台最常用也是最重要的功能之一.根据微信 ...
- Java中各类Cache机制实现解决方案[来自CSDN]
摘要:在Java中,不同的类都有自己单独的Cache机制,实现的方法也可能有所不同,文章列举了Java中常见的各类Cache机制的实现方法,同时进行了综合的比较. 在Java中,不同的类都有自己单独的 ...
随机推荐
- Python2.X和Python3.X中的urllib区别
Urllib是Python提供的一个用于操作URL的模块,在Python2.X中,有Urllib库,也有Urllib2库,在Python3.X中Urllib2合并到了Urllib中,我们爬取网页的时候 ...
- Django模版中的过滤器详细解析 Django filter大全
就象本章前面提到的一样,模板过滤器是在变量被显示前修改它的值的一个简单方法. 过滤器看起来是这样的: {{ name|lower }} 显示的内容是变量 {{ name }} 被过滤器 lower 处 ...
- sqlzoo练习答案--SUM and COUNT
World Country Profile: Aggregate functions This tutorial is about aggregate functions such as COUNT, ...
- linux性能不好怎么办?对着清单撸一遍
性能不好怎么办?对着清单撸一遍 Brendan Gregg是Netflix的资深性能架构师,著名性能调优专家.著有<性能之巅:洞悉系统.企业与云计算>)一书,可以说是性能调优领域的集大成之 ...
- map area 标签的使用
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- echarts 百度图表
手册说明 http://echarts.baidu.com/option.html 3.0版本加了很多新属性可以看以上链接 此文用的3.x版本 第一步 引入 <script src=" ...
- 方程式漏洞之复现window2008/win7 远程命令执行漏洞
前几天就想写的,因为一些缘故就没写.此次是在外网环境下进行的.大家在内网中也一个样. 方法: 使用Eternalblue模块,剑测是否有漏洞然后msf生成一个dll直接反弹shell. PS:win版 ...
- Pgsql特殊排序
对字段值为A,B,C,D的时候进行特殊排序. CASE WHEN aa = 'H' THEN ' WHENaa = 'O' THEN ' ELSE aa END 对数字进行排序,升序,0排到最后面 C ...
- [shell]C语言调用shell脚本接口
Use popen if you want to run a shell command and want the parent process to be able to talk to the c ...
- const成员或者引用成员必须使用构造函数初始化列表的方式
#include<iostream.h> class A { const int a; int b; }; void main() { A obja; }编译出现如下错误:error C2 ...