配置本地maven,File-Settings-maven
初始版本为如下,需要在pom文件增加一些数据库支持
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基础配置完成
下一步 创建数据库信息并导入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;
根据数据库信息创建实体类
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层
controller层
在springboot启动类上配置包扫描注解
整合完毕,进行CRUD,查询所有测试
踩坑点:要使用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
最终显示效果如下
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";
}
}