第一步:我们根据这个类定义数据库,并插入菜单数据
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');
第二步:引入相应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); } }