数据库设计

我们在设计数据库的时候仅仅使用一张表就可以把上面的关系给捋清楚,就是通过一个parentid字段,让我们开看一下这张表的表结构

看一下建表语句

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

实体类

import lombok.Data;
import java.io.Serializable;
import java.util.List;
@Data
public class Menu implements Comparable<Menu>, Serializable {private static final long serialVersionUID = -4866555859812317355L;private Integer id;private String name;private Integer parentId;private String url;private String icon;private Integer order;//子菜单列表private List<Menu> children;@Overridepublic int compareTo(Menu o) {if(this.order != o.order){return this.order - o.order;}return 0;}
}

先看看controller层:

@Autowiredprivate MenuService menuService;@RequestMapping(value = "/menu/findTree",method = RequestMethod.POST)public BaseResponse create(@RequestBody(required = false) Menu menu) {List<Menu> list = menuService.findAll(menu);return BaseResponse.ok(list);}

service接口

import com.free.freedom.entity.Menu;
import java.util.List;
public interface MenuService {List<Menu> findAll(Menu menu);
}

实现类

import com.free.freedom.entity.Menu;
import com.free.freedom.mapper.MenuMapper;
import com.free.freedom.service.MenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;@Service
public class MenuServiceImpl implements MenuService {@Autowiredprivate MenuMapper menuMapper;@Overridepublic List<Menu> findAll(Menu menu) {try {//查询出所有的菜单List<Menu> allMenu = menuMapper.findAll();//根节点存储List<Menu> rootMenu = new ArrayList<>();//根据传递的参数设置根节点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);//为根节点设置子菜单,getChild是递归调用for (Menu nv : rootMenu) {//获取根节点下的所有子节点,使用getChild方法List<Menu> childList = getChild(nv.getId(),allMenu);//给根节点设置子节点nv.setChildren(childList);}return rootMenu;} catch (Exception e) {e.printStackTrace();return new ArrayList<>();}}private List<Menu> getChild(Integer id, List<Menu> allMenu) {//子菜单List<Menu> childList = new ArrayList<>();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;}
}

mapper层

import com.free.freedom.entity.Menu;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface MenuMapper {List<Menu> findAll();
}

mapper.xml

<?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.free.freedom.mapper.MenuMapper"><resultMap id="BaseResultMap" type="com.free.freedom.entity.Menu"><id column="id" jdbcType="INTEGER" property="id" /><result column="name" jdbcType="VARCHAR" property="name" /><result column="parentid" jdbcType="INTEGER" property="parentId" /><result column="url" jdbcType="VARCHAR" property="url" /><result column="icon" jdbcType="VARCHAR" property="icon" /><result column="order" jdbcType="INTEGER" property="order" /></resultMap><select id="findAll" resultMap="BaseResultMap">select * from menu</select>
</mapper>

测试结果

在这里插入图片描述

{
“status”: 0,
“msg”: “OK”,
“data”: [
{
“id”: 1,
“name”: “新闻”,
“parentId”: 0,
“url”: “/www/xinwen”,
“icon”: “xxx”,
“order”: 1,
“children”: [
{
“id”: 3,
“name”: “每日晚报”,
“parentId”: 1,
“url”: “/www/zaobao”,
“icon”: “xxx”,
“order”: 1,
“children”: []
},
{
“id”: 2,
“name”: “每日日报”,
“parentId”: 1,
“url”: “/www/meiriribao”,
“icon”: “xxx”,
“order”: 2,
“children”: [
{
“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”: 9,
“name”: “联播”,
“parentId”: 0,
“url”: “/www/xinwen”,
“icon”: “xxx”,
“order”: 1,
“children”: []
}
] }

{
“status”: 0,
“msg”: “OK”,
“data”: [
{
“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有话说

Java递归实现多级菜单相关推荐

  1. java递归实现多级菜单栏_vue+ java 实现多级菜单递归效果

    效果如图: 大概思路:树形视图使用的是vue官方事例代码,java负责封装数据,按照vue官方事例的数据结构封装数据即可.有两个需要关注的点: 1.官方事例的数据结构是一个对象里面包含着集合,而不是一 ...

  2. java递归实现多级菜单栏_Java构建树形菜单以及支持多级菜单的实例代码

    这篇文章主要介绍了Java构建树形菜单的实例代码(支持多级菜单),非常不错,具有参考借鉴价值,需要的朋友可以参考下 效果图:支持多级菜单. 菜单实体类: public class Menu { // ...

  3. java递归把list菜单列表转为菜单树

    java递归把列表转为菜单树 菜单实体类 package com.utils.menu;import java.util.List;public class Menu {private String ...

  4. java递归实现多级树

    java 递归使用范例 javaBean package cn.webname.test;import java.util.List;public class RegionBeanTree {priv ...

  5. mysql vue 菜谱_vue+ java 实现多级菜单递归效果

    效果如图: 大概思路:树形视图使用的是vue官方事例代码,java负责封装数据,按照vue官方事例的数据结构封装数据即可.有两个需要关注的点: 1.官方事例的数据结构是一个对象里面包含着集合,而不是一 ...

  6. java中菜单分几级_JAVA构造多级菜单

    很多时候我们在前段展现时要用到多级菜单,刚好今天做了个简单的,整理一下: 首先我们要确定要展现的菜单结构: --根菜单 --一级菜单A --二级菜单A --三级菜单A --一级菜单B 与Hiberna ...

  7. java多级菜单列表怎么做_JAVA构造多级菜单

    很多时候我们在前段展现时要用到多级菜单,刚好今天做了个简单的,整理一下: 首先我们要确定要展现的菜单结构: --根菜单 --一级菜单A --二级菜单A --三级菜单A --一级菜单B 与Hiberna ...

  8. Java 实现 多级菜单

    一:前言 最近老师布置了给多级菜单的作业,感觉蛮有意思的,可以提升自己的逻辑!下面我写个简易版的多级菜单,本人还是菜鸟,欢迎各位给予宝贵的建议! 二:正文 由于是给各位演示,所有我把涉及的其他条件全省 ...

  9. java 递归查询多级菜单

    类目表是多级目录表,数据如下: 想获取所有数据的多级目录,代码如下: /*** 获取树形接口的 类目** @return*/@Overridepublic List<ExamCategory&g ...

最新文章

  1. Android(Linux)实时监控串口数据
  2. CCS MAP文件说明
  3. Android调用前置摄像头的方法
  4. matlab相关的数字信号,数字信号处理及其MATLAB实现.ppt
  5. java中怎样创建多个对象,java中StringBuilder.appent方法创建几个对象
  6. dlib 怎么安装vs2017_win10中的dlib库安装过程
  7. MySQL Proxy和 Amoeba 工作机制浅析
  8. element ui html编辑器,Vue + Element UI使用富文本编辑器
  9. 【vue】【element】el-table列表中设计一个颜色块
  10. 线程池作用及Executors方法讲解
  11. 2019最新《网易云课堂C++开发工程师案例-网吧收银系统(MFC+ADO)》
  12. 人工智能目前有哪些突破?
  13. 深海迷航坐标传送代码_深海迷航全控制台代码汇总 深海迷航物品作弊码大全...
  14. win7快速启动栏计算机,win7快速启动栏,教您Win7如何添加快速启动栏
  15. halcon中的分水岭算法讲解以及作用和实例
  16. 超详细的WMS仓储管理系统介绍——盘点篇
  17. RGB LED 七彩跳变
  18. 毕业设计 基于深度学习的人脸性别年龄识别 - 图像识别 opencv
  19. 如何通俗的理解函数的极限_如何理解函数的极限?
  20. 临床宏基因组学的应用

热门文章

  1. 项目交接后的工作流程及要求
  2. 066访问二进制文件
  3. 使用化学烧伤创建自定义的详细木材燃烧图案
  4. MSXML2.ServerXMLHTTP
  5. 【php】获取路径(目录)
  6. 自考第三波+GCT考试总结
  7. ArcGIS教程:克里金法的工作原理(二)
  8. k近邻法: k-nearest neighbor
  9. 网络安全与渗透:内网dns劫持——ettercap(三)此生无悔入华夏,男儿何不带吴钩
  10. 华为OD机试ACM输入输出