菜单根据菜单ID向下递归
第一步:我们根据这个类定义数据库,并插入菜单数据
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 '' COMMENT '菜单顺序',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='菜单表'; -- ----------------------------
-- Records of jrbac_menu
-- ----------------------------
INSERT INTO `jrbac_menu` VALUES ('', 'Forms', null, 'forms.html', 'fa fa-edit', '');
INSERT INTO `jrbac_menu` VALUES ('', 'UI Elements', null, '', 'fa fa-wrench', '');
INSERT INTO `jrbac_menu` VALUES ('', 'Buttons', '', 'buttons.html', '', '');
INSERT INTO `jrbac_menu` VALUES ('', 'Icons', '', 'icons.html', null, '');
INSERT INTO `jrbac_menu` VALUES ('', 'Multi-Level Dropdown', '', '', 'fa fa-sitemap', '');
INSERT INTO `jrbac_menu` VALUES ('', 'Second Level Item', '', 'second.html', null, '');
INSERT INTO `jrbac_menu` VALUES ('', 'Third Level', '', null, '', '');
INSERT INTO `jrbac_menu` VALUES ('', 'Third Level Item', '', 'third.html', null, '');
第二步:引入相应pom
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <groupId>com.payease</groupId>
<artifactId>sell</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging> <name>sell</name>
<description>Demo project for Spring Boot</description> <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.8.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties> <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency> <!-- ===================== mysql驱动 ======================== -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- ===================== jpa ======================== -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency> <!-- ===================== @Getter @Setter @Slf4j @Data ======================== -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency> <!-- ===================== google: gson ======================== -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency> <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.36</version>
</dependency> <!-- https://mvnrepository.com/artifact/com.github.binarywang/weixin-java-mp -->
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-mp</artifactId>
<version>2.7.0</version>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency> <dependency>
<groupId>cn.springboot</groupId>
<artifactId>best-pay-sdk</artifactId>
<version>1.1.0</version>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
</dependencies> <build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build> </project>
第三步:相应数据库的实体类(把数据库的那张表jrbac_menu 改为 menu)
package com.payease.dataobject; import lombok.Data; import javax.persistence.Entity;
import javax.persistence.Id; /**
* 菜单循环递归类
* @Created By liuxiaoming
* @CreateTime 2017/12/7 下午12:46
**/
@Entity
@Data
public class Menu {
// 菜单id
@Id
private String id;
// 菜单名称
private String name;
// 父菜单id
private String parentId;
// 菜单url
private String url;
// 菜单图标
private String icon;
// 菜单顺序
private int order; // ... 省去getter和setter方法以及toString方法
}
第四步:树形数据实体接口
package com.payease.utils; import java.util.List; /**
* 树形数据实体接口
* @param <E>
* @Created By liuxiaoming
* @CreateTime 2017/12/7 下午3:39
**/
public interface TreeEntity<E> {
// 菜单id
public String getId();
// 菜单名称
public String getName();
// 父菜单id
public String getParentId();
// 菜单url
public String getUrl();
// 菜单图标
public String getIcon();
// 菜单顺序
public int getOrder(); public void setChildList(List<E> childList); }
第五步:封装类menuVO
package com.payease.VO; import com.payease.utils.TreeEntity;
import lombok.Data; import java.util.List; /**
* @Created By liuxiaoming
* @CreateTime 2017/12/7 下午12:58
**/
@Data
public class MenuVO implements TreeEntity<MenuVO> {
// 菜单id
public String id;
// 菜单名称
public String name;
// 父菜单id
public String parentId;
// 菜单url
public String url;
// 菜单图标
public String icon;
// 菜单顺序
public int order;
// 子菜单
public List<MenuVO> childList; }
第六步:编写 解析树形数据工具类
package com.payease.utils; import org.apache.commons.lang3.StringUtils; import java.util.ArrayList;
import java.util.List; /**
* 解析树形数据工具类
* @Created By liuxiaoming
* @CreateTime 2017/12/7 下午3:41
**/
public class TreeParser{
/**
* 解析树形数据
* @param topId
* @param entityList
* @return
* @Created By liuxiaoming
* @CreateTime 2017/12/7 下午3:41
*/
public static <E extends TreeEntity<E>> List<E> getTreeList(String topId, List<E> entityList) {
List<E> resultList=new ArrayList<>(); //获取顶层元素集合
String parentId;
if(StringUtils.isBlank(topId)){
//全查
for (E entity : entityList) {
parentId=entity.getParentId();
if(StringUtils.isBlank(parentId))
resultList.add(entity);
}
}else{
//根据传入的ID进行向下递归
for (E entity : entityList) {
parentId=entity.getParentId();
if(parentId!=null && topId.equals(parentId)){
resultList.add(entity);
}
}
} //获取每个顶层元素的子数据集合
for (E entity : resultList) {
entity.setChildList(getSubList(entity.getId(),entityList));
} return resultList;
} /**
* 获取子数据集合
* @param id
* @param entityList
* @return
* @Created By liuxiaoming
* @CreateTime 2017/12/7 下午3:41
*/
private static <E extends TreeEntity<E>> List<E> getSubList(String id, List<E> entityList) {
List<E> childList=new ArrayList<>();
String parentId; //子集的直接子对象
for (E entity : entityList) {
parentId=entity.getParentId();
if(id.equals(parentId)){
childList.add(entity);
}else{ }
} //子集的间接子对象
for (E entity : childList) {
entity.setChildList(getSubList(entity.getId(), entityList));
} //递归退出条件
if(childList.size()==0){
return null;
} return childList;
} }
第七步:编写对应的dao层
package com.payease.repository; import com.payease.dataobject.Menu;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository; import java.util.List; /**
* Created by liuxiaoming on 2017/11/13.
*/
@Repository
public interface MenuRepository extends JpaRepository<Menu, String> { List<Menu> findById(String orderId);
}
第八步:编写测试类
package com.payease.repository; import com.alibaba.fastjson.JSON;
import com.google.gson.Gson;
import com.payease.VO.MenuVO;
import com.payease.dataobject.Menu;
import com.payease.utils.TreeParser;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner; import java.util.ArrayList;
import java.util.List; /**
* @Created By liuxiaoming
* @CreateTime 2017/12/7 下午12:51
**/
@RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
public class MenuRepositoryTest { @Autowired
private MenuRepository repository;
@Test
public void findById() throws Exception {
// 原始的数据
List<Menu> rootMenu = repository.findAll();
// 查看结果
List<MenuVO> rootMenuVO = new ArrayList<>();
for (Menu menu : rootMenu) {
MenuVO menuVO = new MenuVO();
BeanUtils.copyProperties(menu,menuVO);
rootMenuVO.add(menuVO);
// System.out.println("rootMenu:" + menuVO.toString());
} List<MenuVO> child = TreeParser.getTreeList("2",rootMenuVO); List<MenuVO> menus = TreeParser.getTreeList("2",rootMenuVO);
System.out.println(menus); Gson gson = new Gson();
String gJson = gson.toJson(menus);
System.out.println("gjson:"+gJson); String fastJson = JSON.toJSONString(child); System.out.println("fastJson:"+fastJson); } }
菜单根据菜单ID向下递归的更多相关文章
- PHP递归获得树形菜单和遍历文件夹下的所有文件以及子文件夹
PHP递归获得树形菜单和遍历文件夹下的所有文件以及子文件夹 一.使用递归获取树形菜单 数据表category(id,name,parent_id) <?php class category{ / ...
- #AOS应用基础平台# 添加了用户自己定义快捷菜单在平铺布局下的用户自己定义排序管理
#AOS开发平台# 添加了用户自己定义快捷菜单在平铺布局下的用户自己定义排序管理.
- jq自定义下拉菜单,在点击非当前下拉菜单区域时,关闭下拉菜单(点击事件的对象不是目标元素本身)
jq自定义下拉菜单,在点击非当前下拉菜单区域时,关闭下拉菜单(点击事件的对象不是目标元素本身) //点击非当前下拉菜单区域时,关闭下拉菜单 $(document).mousedown(function ...
- jq自定义下拉菜单,当用户点击非自身元素(下拉菜单)本身时关闭下拉菜单
jq自定义下拉菜单,当用户点击非自身元素(下拉菜单)本身时关闭下拉菜单 截图: 代码如下: //关闭用户菜单 $(document).mousedown(function(e){ var _con = ...
- 自定义右键菜单,禁用浏览器自带的右键菜单[右键菜单实现--Demo]
许多从事Web开发的会发现有些事,我们需要禁用浏览器本事自带的右键菜单,而实现自定义的右键菜单下面我们也来实现一个自定义的右键菜单 首先来创建JSP页面 <%@ page language=&q ...
- 微信公众号开发C#系列-8、自定义菜单及菜单响应事件的处理
1.概述 自定义菜单能够帮助公众号丰富界面,让用户更好更快地理解公众号的功能.菜单分为默认菜单与个性化菜单.个性化菜单接口是为了帮助公众号实现灵活的业务运营,开发者可以通过该接口,让公众号的不同用户群 ...
- VS2010/MFC编程入门之三十五(菜单:菜单及CMenu类的使用)
鸡啄米在上一节中讲的是VS2010的菜单资源,本节主要讲菜单及CMenu类的使用. CMenu类的主要成员函数 MFC为菜单的操作提供了CMenu类,下面鸡啄米就常用的几个成员函数进行简单的介绍. B ...
- Android_(菜单)选项菜单
Android系统中菜单分为Options Menu.Context Menu.Sub Men三种 Options Menu和Context Menu属于一级菜单 Sub Menu属于Options ...
- VS2010-MFC(菜单:菜单及CMenu类的使用)
转自:http://www.jizhuomi.com/software/212.html 上一节讲的是VS2010的菜单资源,本节主要讲菜单及CMenu类的使用. CMenu类的主要成员函数 MFC为 ...
随机推荐
- SGU 194 Reactor Cooling (有容量和下界的可行流)
题意:给定上一个有容量和下界的网络,让你求出一组可行解. 析:先建立一个超级源点 s 和汇点 t ,然后在输入时记录到每个结点的下界的和,建边的时候就建立c - b的最后再建立 s 和 t , 在建立 ...
- eclipse find 两位数
查找两位数
- SpringMVC源码解读 - HandlerMapping
SpringMVC在请求到handler处理器的分发这步是通过HandlerMapping模块解决的.handlerMapping 还处理拦截器. 先看看HandlerMapping的继承树吧 可以大 ...
- 测试用数据库表设计和SessionFactory
本篇为struts-2.5.2和spring-3.2.0以及hibernate-4.2.21的整合开篇. 一.测试的数据库表. 用户.角色和权限关系表.数据库是Mysql5.6.为了考虑到一些特殊数据 ...
- 团体程序设计天梯赛L2-001 紧急救援 2017-03-22 17:25 93人阅读 评论(0) 收藏
L2-001. 紧急救援 时间限制 200 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 作为一个城市的应急救援队伍的负责人,你有一张特殊的全国 ...
- leancloud 云引擎
可以部署网站的云端,云代码的升级版.
- log4j打印MyBatis的sql语句配置
log4j.rootLogger=DEBUG,stdout log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender. ...
- merge sort 的javascript实现
递归 上一篇blog里,用js实现了quicksort算法,quicksort算法是一个递归调用过程. 递归是一种非常强大的编程思想,它广泛的的存在于各种语言当中,尤其lisp的各种方言中,大量的使用 ...
- 用.msi安装node时安装失败,出现rolling back action(转载)
转载地址:https://blog.csdn.net/qq_33295622/article/details/52956369在重装node时出现了上图所示情况,解决方法如下: 1.在官网下载稳定版本 ...
- (zxing.net)一维码UPC E的简介、实现与解码
UPC(Universal Product Code)码是最早大规模应用的条码,其特性是一种长度固定.连续性的条 码,目前主要在美国和加拿大使用,由于其应用范围广泛,故又被称万用条码. UPC码仅可 ...