Stream流实现Tree树状结构无限递归

  1.  新建一个SpringBoot框架项目

Stream流实现Tree树状结构无限递归_第1张图片

Stream流实现Tree树状结构无限递归_第2张图片

Stream流实现Tree树状结构无限递归_第3张图片

配置本地maven,File-Settings-maven

 初始版本为如下,需要在pom文件增加一些数据库支持

 Stream流实现Tree树状结构无限递归_第4张图片



    4.0.0
    
        org.springframework.boot
        spring-boot-starter-parent
        2.5.6
         
    
    com.treedemo
    demo
    0.0.1-SNAPSHOT
    demo
    Demo project for Spring Boot
    
        1.8
    
    
        
            org.springframework.boot
            spring-boot-starter-web
        

        
        
            mysql
            mysql-connector-java
            8.0.26
        

        
        
            com.baomidou
            mybatis-plus-boot-starter
            3.4.2
        
        
        
            org.projectlombok
            lombok
            true
            1.18.20
        
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        
        
            org.apache.commons
            commons-lang3
            3.12.0
        
        
        org.springframework.boot
        spring-boot-starter-freemarker
    
    

    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
            
        
    


在yaml配置文件里设置端口号等数据库链接信息和freemark支持

server:
  port: 9100

spring:
  freemarker:
    suffix: .html
    cache: false
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss
    time-zone: GMT+8
    locale: zh_CN
    generator:
      write-numbers-as-strings: true
      write-bigdecimal-as-plain: true
    serialization:
      write-dates-as-timestamps: false
  datasource:
    type: com.zaxxer.hikari.HikariDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/demo?serverTimezone=GMT%2b8&useUnicode=true&characterEncoding=utf-8&useSSL=false
    username: root
    password: 123456
    hikari:
      connection-timeout: 60000
      validation-timeout: 3000
      idle-timeout: 60000
      login-timeout: 5
      max-lifetime: 60000
      maximum-pool-size: 30
      minimum-idle: 10
      read-only: false

# mybatis-plus
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  mapper-locations: classpath*:/mapper/*.xml


logging:
  level:
    root: info

SpringBoot基础配置完成

Stream流实现Tree树状结构无限递归_第5张图片

下一步 创建数据库信息并导入sql

/*
 Navicat MySQL Data Transfer

 Source Server         : 本地数据库
 Source Server Type    : MySQL
 Source Server Version : 50734
 Source Host           : localhost:3306
 Source Schema         : demo

 Target Server Type    : MySQL
 Target Server Version : 50734
 File Encoding         : 65001

 Date: 20/10/2020 22:42:06
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for kss_course_category
-- ----------------------------
DROP TABLE IF EXISTS `kss_course_category`;
CREATE TABLE `kss_course_category`  (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT ' 主键',
  `title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '分类名称',
  `descrciption` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '分类描述',
  `mark` int(1) NULL DEFAULT NULL COMMENT '是否更新',
  `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
  `update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间',
  `type` int(1) NULL DEFAULT NULL COMMENT '类型1文件夹 2文件',
  `pid` int(11) NULL DEFAULT NULL COMMENT '父ID',
  `status` int(1) NULL DEFAULT NULL COMMENT '发布状态1发布 0未发布',
  `isexpand` bit(1) NULL DEFAULT NULL COMMENT '0收起 1展开',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 12 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of kss_course_category
-- ----------------------------
INSERT INTO `kss_course_category` VALUES (1, 'Java', 'Java', 1, '2021-10-18 14:19:05', '2021-10-18 14:19:05', 1, 0, 1, b'1');
INSERT INTO `kss_course_category` VALUES (2, 'Js', 'Js', 1, '2021-10-18 14:19:05', '2021-10-18 14:19:05', 1, 0, 1, b'0');
INSERT INTO `kss_course_category` VALUES (3, 'Go', 'Go', 1, '2021-10-18 14:19:05', '2021-10-18 14:19:05', 1, 0, 1, b'0');
INSERT INTO `kss_course_category` VALUES (4, 'Python', 'Python', 1, '2021-10-18 14:19:05', '2021-10-18 14:19:05', 1, 0, 1, b'0');
INSERT INTO `kss_course_category` VALUES (5, 'Java面向对象', 'Java面向对象', 1, '2021-10-18 14:19:05', '2021-10-18 14:19:05', 1, 1, 1, b'0');
INSERT INTO `kss_course_category` VALUES (6, 'Spring', 'Spring', 1, '2021-10-18 14:19:05', '2021-10-18 14:19:05', 1, 1, 1, b'0');
INSERT INTO `kss_course_category` VALUES (7, 'SpringMvc', 'SpringMvc', 1, '2021-10-18 14:19:05', '2021-10-18 14:19:05', 2, 6, 1, b'0');
INSERT INTO `kss_course_category` VALUES (8, 'SpringBoot', 'SpringBoot', 1, '2021-10-18 14:19:05', '2021-10-18 14:19:05', 2, 6, 1, b'0');
INSERT INTO `kss_course_category` VALUES (9, 'Mybatis', 'Mybatis', 1, '2021-10-18 14:19:05', '2021-10-18 14:19:05', 1, 1, 1, b'0');
INSERT INTO `kss_course_category` VALUES (10, 'MybatisPlus', 'MybatisPlus', 1, '2021-10-18 14:19:05', '2021-10-18 14:19:05', 1, 9, 1, b'0');
INSERT INTO `kss_course_category` VALUES (11, 'nodejs', 'MybatisPlus', 1, '2021-10-18 14:19:05', '2021-10-18 14:19:05', 1, 2, 1, b'0');

SET FOREIGN_KEY_CHECKS = 1;

根据数据库信息创建实体类

Stream流实现Tree树状结构无限递归_第6张图片

package com.treedemo.demo.pojo;

import com.baomidou.mybatisplus.annotation.*;
import lombok.*;

import java.util.Date;
import java.util.List;

@Data
@ToString
@Builder
@AllArgsConstructor
@NoArgsConstructor
@TableName("kss_course_category")
public class CourseCategory implements java.io.Serializable {

    @TableId(type = IdType.AUTO)
    private Integer id;
    // 上课标题
    private String title;
    // 分类描述
    private String descrciption;
    // 是否更新
    private Integer mark;
    // 发布状态1发布 0未发布
    private Integer status;
    // 类型 1文件夹 2文件
    private Integer type;
    // 父id =0 根集 其它全部都是子集
    private Integer pid;
    //  排序
    private Integer sorted;
    // 是否展开和收起
    private Boolean isexpand;
    // 这里一定加exist=false ,代表当前这个字段不在表中,不加就会报错
    @TableField(exist = false)
    private List childrenList;
    // 创建时间
    @TableField(fill = FieldFill.INSERT)//在新增的时候填充
    private Date createTime;
    // 更新时间
    @TableField(fill = FieldFill.INSERT_UPDATE)//在新增的时候填充
    private Date updateTime;
}

mapper层

Stream流实现Tree树状结构无限递归_第7张图片service层

 Stream流实现Tree树状结构无限递归_第8张图片

 Stream流实现Tree树状结构无限递归_第9张图片

 Stream流实现Tree树状结构无限递归_第10张图片

controller层

 Stream流实现Tree树状结构无限递归_第11张图片

 在springboot启动类上配置包扫描注解

Stream流实现Tree树状结构无限递归_第12张图片

整合完毕,进行CRUD,查询所有测试

Stream流实现Tree树状结构无限递归_第13张图片

Stream流实现Tree树状结构无限递归_第14张图片

 踩坑点:要使用lombook必须在idea中设置启用lombook

先查询父节点和非父节点,在递归查询子孩子,核心代码如下

package com.treedemo.demo.service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.treedemo.demo.mapper.CourserCategoryMapper;
import com.treedemo.demo.pojo.CourseCategory;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;


@Service
@Log4j2
public class CourseCategoryServiceImpl extends ServiceImpl
        implements CourseCategoryService {


    public List findCategoiresTree() {
        // 1 :查询表中所有的数据
        List allList = this.list(); // 思考空间,为什么查询的是所有
        // 2: 找到所有的根节点 pid = 0,并排序
        List rootList=allList.stream()
                .filter(category -> category.getPid().equals(0))
                .sorted((e1,e2)->e1.getSorted()-e2.getSorted()).collect(Collectors.toList());
        //查询所有非父节点
        List subList=allList.stream()
                .filter(e->!e.getPid().equals(0)).collect(Collectors.toList());
        //循环根节点查找对应的子节点
           rootList.forEach(e->findChildrenNode(e,subList));
        return rootList;
    }

    //递归查找子节点方法, 参数 一个根节点,所有非根节点集合
    private void findChildrenNode(CourseCategory root,List subList){
        //通过根节点id和子节点pid是否相等,如果相等代表当前根的子集
        List childrenLList=subList.stream()
                .filter(category->category.getPid().equals(root.getId()))
                .sorted((e1,e2)->e1.getSorted()-e2.getSorted()).collect(Collectors.toList());

        if(!CollectionUtils.isEmpty(childrenLList)){
            root.setChildenList(childrenLList);//赋值
           //再次递归查询根节点孩子是否还有孩子
            childrenLList.forEach(e->findChildrenNode(e,subList));
        }else {
            //如果当前没有一个子节点,初始化一个空数组
            root.setChildenList(new ArrayList<>());
        }
    }





}

优雅的显示前端插件https://github.com/gildas-lormeau/JSONView-for-Chromehttps://github.com/gildas-lormeau/JSONView-for-Chrome

最终显示效果如下

 Stream流实现Tree树状结构无限递归_第15张图片

  1. 使用axios组件完成异步接口调用和引入 vue和axios js依赖
  2. 新建tree.html内容如下
  3. 
    
    
        
        
        
        tree菜单
        
    
    
    
    

    {{title}}

    调用接口访问:

    package com.treedemo.demo.controller;
    
    import com.fasterxml.jackson.databind.util.JSONPObject;
    import com.treedemo.demo.pojo.CourseCategory;
    import com.treedemo.demo.service.CourseCategoryService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.servlet.ModelAndView;
    
    import javax.annotation.Resource;
    import java.util.List;
    
    @Controller
    public class CourseCategoryController {
    @Resource
        CourseCategoryService courseCategoryService;
        @GetMapping("/api/catagory/tree")
        @ResponseBody
        public List getTree(){
    
            return courseCategoryService.findCategoiresTree();
        }
    
    
        //resource资源路径下的不能直接访问,只能通过路由跳转
        @GetMapping("/tree")
        public  String  treePage(){
            return "tree";
        }
    }
    

    Stream流实现Tree树状结构无限递归_第16张图片

     

你可能感兴趣的:(java,spring,boot,后端,java)