当前位置: 首页 > news >正文

springboot树形结构接口, 懒加载实现

数据库关系有父子id的, 作为菜单栏展示时需要用前端需要用到懒加载, 所谓懒加载就是接口有一个标志位isLeaf, 前端请求后通过该字段判断该节点是否还有子节点数据

创建数据库表 t_company_info结构有id和parentId标识, 用来表示父子关系

/*Navicat Premium Data TransferSource Server         : mysql8.0Source Server Type    : MySQLSource Server Version : 80029 (8.0.29)Source Host           : localhost:3307Source Schema         : springboot_mybatisTarget Server Type    : MySQLTarget Server Version : 80029 (8.0.29)File Encoding         : 65001*/SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;-- ----------------------------
-- Table structure for t_company_info
-- ----------------------------
DROP TABLE IF EXISTS `t_company_info`;
CREATE TABLE `t_company_info`  (`id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT 'id',`company_name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '公司名',`parent_id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '父节点id',PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin ROW_FORMAT = Dynamic;-- ----------------------------
-- Records of t_company_info
-- ----------------------------
INSERT INTO `t_company_info` VALUES ('1', '旺旺集团', '0');
INSERT INTO `t_company_info` VALUES ('2', '广州分部', '1');
INSERT INTO `t_company_info` VALUES ('3', '深圳分部', '1');
INSERT INTO `t_company_info` VALUES ('4', '福田区分公司', '3');
INSERT INTO `t_company_info` VALUES ('5', '南山区分公司', '3');SET FOREIGN_KEY_CHECKS = 1;

有需要的配置文件 application.yml 可参考

spring:datasource:username: #填写账号password: #填写密码url: jdbc:mysql://localhost:3307/springboot_mybatis?useSSL=false&useUnicode=true&characterEncoding=UTF-8&allowPublicKeyRetrieval=true#&allowPublicKeyRetrieval=true这一部分设置是mysql8里面的, 不设置验证会报错driver-class-name: com.mysql.cj.jdbc.Drivertype: com.alibaba.druid.pool.DruidDataSourcedruid:stat-view-servlet:enabled: truelogin-username: login-password: web-stat-filter:enabled: true#  sql:
#    init:
#      schema-locations: classpath:sql/schema.sql
#      mode: always
server:port: 8089logging:level:root: info  #日志等级com.example.mybatis_plus: info
mybatis-plus:configuration:map-underscore-to-camel-case: true  #下划线转驼峰global-config:db-config:logic-not-delete-value: 0  #逻辑删除logic-delete-field: 1
#  type-enums-package: com.example.mybatis_plus.enums.statusEnum
1.创建实体类
package com.example.mybatis_plus.entity;import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;import java.io.Serializable;/*** <p>* * </p>** @author * @since 2023-04-01*/
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("t_company_info")
@ApiModel(value="CompanyInfo对象", description="")
public class CompanyInfo implements Serializable {private static final long serialVersionUID = 1L;@ApiModelProperty(value = "id")@TableId(value = "id", type = IdType.ASSIGN_UUID)private String id;@ApiModelProperty(value = "公司名")private String companyName;@ApiModelProperty(value = "父节点id")private String parentId;}
2.创建service接口
package com.example.mybatis_plus.service;import com.baomidou.mybatisplus.extension.service.IService;
import com.example.mybatis_plus.entity.CompanyInfo;import java.util.List;/*** <p>*  服务类* </p>** @author * @since 2023-04-01*/
public interface CompanyInfoService extends IService<CompanyInfo> {/*** 获得指定父节点的子节点列表* @param parentId 父节点ID* @return 子节点列表*/List<CompanyInfo> getChildNodes(String parentId);
}
3.完成其实现类
package com.example.mybatis_plus.service.impl;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.mybatis_plus.entity.CompanyInfo;
import com.example.mybatis_plus.mapper.CompanyInfoMapper;
import com.example.mybatis_plus.service.CompanyInfoService;
import org.springframework.stereotype.Service;import java.util.List;/*** <p>*  服务实现类* </p>** @author * @since 2023-04-01*/
@Service
public class CompanyInfoServiceImpl extends ServiceImpl<CompanyInfoMapper, CompanyInfo> implements CompanyInfoService {@Overridepublic List<CompanyInfo> getChildNodes(String parentId) {List<CompanyInfo> list=list(new QueryWrapper<CompanyInfo>().eq("parent_id",parentId));return list;}
}
4.mapper接口
package com.example.mybatis_plus.mapper;import com.example.mybatis_plus.entity.CompanyInfo;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;/*** <p>*  Mapper 接口* </p>** @author * @since 2023-04-01*/
public interface CompanyInfoMapper extends BaseMapper<CompanyInfo> {}
5.mapper文件
<?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.example.mybatis_plus.mapper.CompanyInfoMapper"><!-- 通用查询映射结果 --><resultMap id="BaseResultMap" type="com.example.mybatis_plus.entity.CompanyInfo"><id column="id" property="id" /><result column="company_name" property="companyName" /><result column="parent_id" property="parentId" /></resultMap><!-- 通用查询结果列 --><sql id="Base_Column_List">id, company_name, parent_id</sql></mapper>
6.result统一结果封装类
@Data
public class Result implements Serializable {private int code;private String msg;private Object data;public static Result success(Object data) {return success(200, "操作成功", data);}public static Result success() {return success(200, "操作成功", null);}public static Result success(int code, String msg, Object data) {Result r = new Result();r.setCode(code);r.setMsg(msg);r.setData(data);return r;}public static Result fail(String msg) {return fail(400, msg, null);}public static Result fail(int code, String msg, Object data) {Result r = new Result();r.setCode(code);r.setMsg(msg);r.setData(data);return r;}}
6.创建树形结构实体类TreeNode
package com.example.mybatis_plus.entity;import lombok.Data;/*** @author * @description TODO* @date 2023-04-01*/
@Data
public class TreeNode {private String id;private String companyName;private String parentId;private Boolean isLeaf;public TreeNode(String id, String companyName, String parentId, Boolean isLeaf) {this.id = id;this.companyName = companyName;this.parentId = parentId;this.isLeaf = isLeaf;}
}
7.CompanyInfoController控制层
package com.example.mybatis_plus.controller;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.mybatis_plus.common.Result;
import com.example.mybatis_plus.entity.CompanyInfo;
import com.example.mybatis_plus.entity.TreeNode;
import com.example.mybatis_plus.service.CompanyInfoService;
import com.example.mybatis_plus.utils.ParamUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;/*** <p>* * </p>** @author * @since 2023-04-01*/
@Api(value = "", tags = "")
@RestController
@RequestMapping("/companyInfo")
//@Slf4j
public class CompanyInfoController {@Autowiredprivate CompanyInfoService companyInfoService;@ApiOperation(value = "查询分页数据")@PostMapping(value = "/list")public Result list(@RequestBody(required = false) Map<String, Object> object) {Page<CompanyInfo> page = ParamUtils.toPage(CompanyInfo.class, object);CompanyInfo entity = ParamUtils.toEntity(CompanyInfo.class, object);QueryWrapper<CompanyInfo> qw = new QueryWrapper<>();if (null != entity) {qw.setEntity(entity);}// qw.orderByAsc("");page = companyInfoService.page(page, qw);return Result.success(page);}@ApiOperation(value = "根据id查询数据")@GetMapping(value = "/get")public Result get(String id) {if (null == id || id.equals("")) {return Result.fail("ID不能为空!");}CompanyInfo entity = companyInfoService.getById(id);return Result.success(entity);}/*** 输入 parentId** @param map* @return*/@ApiOperation(value = "获得指定父节点的子节点列表")@PostMapping(value = "/getChildNodes")public Result getChildNodes(@RequestBody Map<String, Object> map) {if (map.isEmpty()) {return Result.fail("输入格式错误");}String parentId = ParamUtils.toString(map, "parentId");
//        List<CompanyInfo> ngPowerTransformerInfoList = CompanyInfoService.getChildNodes(parentId);List<CompanyInfo> ngPowerTransformerInfoList = companyInfoService.getChildNodes(parentId);ArrayList<TreeNode> treeNodes = new ArrayList<>();for (CompanyInfo CompanyInfo : ngPowerTransformerInfoList) {String CompanyId = CompanyInfo.getId();String CompanyParentId = CompanyInfo.getParentId();String companyName = CompanyInfo.getCompanyName();boolean isLeaf = true;List<CompanyInfo> childNodes = companyInfoService.getChildNodes(CompanyId);if (childNodes.size() > 0) {isLeaf = false;}TreeNode treeNode = new TreeNode(CompanyId, companyName, CompanyParentId, isLeaf);treeNodes.add(treeNode);}return Result.success(treeNodes);}@ApiOperation(value = "新增/修改数据")@PostMapping(value = "/save")public Result save(HttpServletRequest request, @RequestBody CompanyInfo entity) {if (null == entity) {return Result.fail("对象不能为空!");}companyInfoService.saveOrUpdate(entity);return Result.success(entity);}@ApiOperation(value = "批量删除数据")@PostMapping(value = "/delete")public Result delete(HttpServletRequest request, @RequestBody List<String> idList) {if (null == idList || idList.isEmpty()) {return Result.fail("对象不能为空!");}companyInfoService.removeByIds(idList);return Result.success();}}

ps

String parentId = ParamUtils.toString(map, "parentId");
ParamUtils工具类有点多, 就不做展示了
就是将map里面的parentId取出来
8.结果演示
8.1请求父节点为0的数据, 只有集团总部, 并且还有子节点所以isLeaf为false

image-20230401222423508

8.2请求父id为1的数据,广州分部没有子节点, isLeaf为true,深圳有子节点,isLeaf为false

image-20230401222606121

8.3请求父id为3的数据, 同理

image-20230401222935783

相关文章:

springboot树形结构接口, 懒加载实现

数据库关系有父子id的, 作为菜单栏展示时需要用前端需要用到懒加载, 所谓懒加载就是接口有一个标志位isLeaf, 前端请求后通过该字段判断该节点是否还有子节点数据 创建数据库表 t_company_info结构有id和parentId标识, 用来表示父子关系 /*Navicat Premium Data TransferSourc…...

java企业级信息系统开发学习笔记02初探spring——利用组件注解符精简spring配置文件

文章目录一、学习目标二、打开01的项目三、利用组件注解符精简spring配置文件&#xff08;一&#xff09;创建新包&#xff0c;复制四个类&#xff08;二&#xff09;修改杀龙任务类&#xff08;三&#xff09;修改救美任务类&#xff08;四&#xff09;修改勇敢骑士类&#xf…...

用Python发送电子邮件?这也太丝滑了吧(21)

小朋友们好&#xff0c;大朋友们好&#xff01; 我是猫妹&#xff0c;一名爱上Python编程的小学生。 欢迎和猫妹一起&#xff0c;趣味学Python。 今日主题 猫爸赚钱养家&#xff0c;细想起来真的不容易啊&#xff01; 起早贪黑&#xff0c;都是6点早起做早饭&#xff0c;送…...

分类预测 | MATLAB实现CNN-GRU-Attention多输入分类预测

分类预测 | MATLAB实现CNN-GRU-Attention多输入分类预测 目录分类预测 | MATLAB实现CNN-GRU-Attention多输入分类预测分类效果模型描述程序设计参考资料分类效果 模型描述 Matlab实现CNN-GRU-Attention多变量分类预测 1.data为数据集&#xff0c;格式为excel&#xff0c;12个输…...

C++提高编程(1)

C提高编程1.模板1.1模板的概念1.2函数模板1.2.1函数模板语法1.2.2函数模板注意事项1.2.3函数模板案例1.2.4普通函数与函数模板的区别1.2.5普通函数与函数模板的调用规则1.2.6模板的局限性1.3类模板1.3.1类模板语法1.3.2类模板和函数模板区别1.3.3类模板中成员函数创建时机1.3.4…...

day26 回溯算法的部分总结

回溯算法的部分总结 回溯算法是一种常用于解决排列组合问题、搜索问题的算法&#xff0c;它的基本思想是将问题的解空间转化为一棵树&#xff0c;通过深度优先搜索的方式遍历树上的所有节点&#xff0c;找到符合条件的解。回溯算法通常使用递归实现&#xff0c;每次递归时传入…...

带你玩转Python爬虫(胆小者勿进)千万别做坏事·······

这节课很危险&#xff0c;哈哈哈哈&#xff0c;逗你们玩的 目录 写在前面 1 了解robots.txt 1.1 基础理解 1.2 使用robots.txt 2 Cookie 2.1 两种cookie处理方式 3 常用爬虫方法 3.1 bs4 3.1.1 基础介绍 3.1.2 bs4使用 3.1.2 使用例子 3.2 xpath 3.2.1 xpath基础介…...

【JavaScript 】严格模式,With关键字,测试框架介绍,assert

❤️ Author&#xff1a; 老九 ☕️ 个人博客&#xff1a;老九的CSDN博客 &#x1f64f; 个人名言&#xff1a;不可控之事 乐观面对 &#x1f60d; 系列专栏&#xff1a; 文章目录静态类型语言弱类型严格模式将过失错误转化为异常简化变量的使用With测试框架try-catch选择性捕获…...

mybatis实现一个简单的CRUD功能的小案例(后端)编写流程

下面是一个使用mybatis实现增删改查功能的示例程序&#xff1a; 1.创建一个数据库 首先需要创建一个名为test_db的数据库&#xff0c;里面包含一个名为user_info的表&#xff0c;其中包含id、name、age三个字段。 2.配置mybatis 在项目的pom.xml文件中添加mybatis和mysql依…...

腾讯云轻量应用服务器价格表(2023版)

2023腾讯云轻量应用服务器2核2G4M带宽88元一年、2核4G6M带宽159元/年、4核8G10M优惠价425元、8核16G14M价格1249、16核32G20M服务器2499元一年&#xff0c;今天分享2023腾讯云服务器配置及精准报价。 腾讯云轻量应用服务器优惠价格表 腾讯云服务器分为轻量应用服务器和云服务器…...

网络层IP协议和数据链路层

目录IP协议协议头格式分片网段划分特殊的IP地址IP地址的数量限制NAT技术NAT技术背景NAT IP转换过程NAPTNAT技术的缺陷NAT和代理服务器私有IP地址和公网IP地址路由路由表生成算法数据链路层认识以太网以太网帧格式认识MAC地址对比理解MAC地址和IP地址认识MTUMTU对IP协议的影响MT…...

零基础学习Java 03

目录 数组 动态初始化数组 静态初始化 数组的应用 数组两种典型的异常 length关键字求出数组的长度 数组遍历在IDEA中输出快捷语句 对象数组 数组的遍历&#xff1a;foreach方法 二维数组 枚举(enum) 数组 1在方法中可以返回一个数组&#xff0c;但是在定义方法时类型要…...

PG数据库超时退出 TCP设定

数据库在使用psql工具以及jdbc进行远程连接时&#xff0c;在经过一定时间之后报错-致命错误&#xff1a; terminating connection due to client no input timeout。 排查安全参数&#xff0c;hg_clientnoinput 0&#xff1b; 问题原因 操作系统TCP相关参数设置不正确&…...

每日学术速递4.4

CV - 计算机视觉 | ML - 机器学习 | RL - 强化学习 | NLP 自然语言处理 Subjects: cs.CL 1.Baize: An Open-Source Chat Model with Parameter-Efficient Tuning on Self-Chat Data 标题&#xff1a;Baize&#xff1a;一种对自聊天数据进行参数高效调优的开源聊天模型 作者…...

ChatGPT将引发大量而普遍的网络安全隐患

ChatGPT是一个基于人工智能的语言生成模型&#xff0c;它可以在任何给定的时间&#xff0c;使用自然语言生成技术&#xff0c;生成文本、对话和文章。它不仅可以被用来编写文本&#xff0c;还可以用来编写语言、生成图像和视频。目前&#xff0c; ChatGPT已广泛应用于语言翻译、…...

购买学生护眼台灯几瓦最好?有哪些推荐护眼灯

现今的近视已然成为普遍现象&#xff0c;而且有往低年龄段发展的趋势。究其原因&#xff0c;长期使用电子设备是一方面&#xff0c;还是就是我们日常工作、学习、生活没有很好的护眼环境&#xff0c;很多时候我们不经意的错误习惯&#xff0c;久而久之就有可能诱发近视。对孩子…...

什么是 SYN 攻击?如何避免 SYN 攻击?

SYN 攻击方式最直接的表现就会把 TCP 半连接队列打满&#xff0c;这样当 TCP 半连接队列满了&#xff0c;后续再在收到 SYN 报文就会丢弃&#xff0c;导致客户端无法和服务端建立连接。 避免 SYN 攻击方式&#xff0c;可以有以下四种方法&#xff1a; 调大 netdev_max_backlo…...

数据分析练习——学习一般分析步骤

目录 一、准备工作 二、导入库和数据 1、导入必要的库&#xff1a; 2、模拟数据 三、数据分析过程 1、读取数据&#xff1a; 2、数据概览和描述性统计&#xff1a; 2.1、查看数据概览&#xff1a; 2.2、查看描述性统计&#xff1a; 3、数据清洗&#xff1a; 3.1、处…...

Linux环境下挂载exfat格式U盘,以及安装exfat文件系统

目录Linux一般支持的文件系统有&#xff1a;1.安装exfat软件安装工具环境以及exfat件依赖的系统软件下载exfat源码包并安装2.挂载exfat格式U盘查看U盘在那个目录执行挂载命令Linux一般支持的文件系统有&#xff1a; 文件系统名称详情ext专门为Linux核心做的第一个文件系统&…...

网格布局grid

grid网格定义 css网格是一个用于web的二维&#xff08;行和列的组合&#xff09;布局&#xff0c;利用网格&#xff0c;你可以把内容按照行和列的格式进行排版&#xff0c;另外&#xff0c;可以轻松的实现复杂布局。 1.定义网格和fr单位 1.1定义网格 在父元素加上&#xff…...

UE5 学习系列(三)创建和移动物体

这篇博客是该系列的第三篇&#xff0c;是在之前两篇博客的基础上展开&#xff0c;主要介绍如何在操作界面中创建和拖动物体&#xff0c;这篇博客跟随的视频链接如下&#xff1a; B 站视频&#xff1a;s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...

uniapp中使用aixos 报错

问题&#xff1a; 在uniapp中使用aixos&#xff0c;运行后报如下错误&#xff1a; AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...

如何在最短时间内提升打ctf(web)的水平?

刚刚刷完2遍 bugku 的 web 题&#xff0c;前来答题。 每个人对刷题理解是不同&#xff0c;有的人是看了writeup就等于刷了&#xff0c;有的人是收藏了writeup就等于刷了&#xff0c;有的人是跟着writeup做了一遍就等于刷了&#xff0c;还有的人是独立思考做了一遍就等于刷了。…...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制

在数字化浪潮席卷全球的今天&#xff0c;数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具&#xff0c;在大规模数据获取中发挥着关键作用。然而&#xff0c;传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时&#xff0c;常出现数据质…...

Springboot社区养老保险系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;社区养老保险系统小程序被用户普遍使用&#xff0c;为方…...

Xen Server服务器释放磁盘空间

disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...

C#中的CLR属性、依赖属性与附加属性

CLR属性的主要特征 封装性&#xff1a; 隐藏字段的实现细节 提供对字段的受控访问 访问控制&#xff1a; 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性&#xff1a; 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑&#xff1a; 可以…...

TSN交换机正在重构工业网络,PROFINET和EtherCAT会被取代吗?

在工业自动化持续演进的今天&#xff0c;通信网络的角色正变得愈发关键。 2025年6月6日&#xff0c;为期三天的华南国际工业博览会在深圳国际会展中心&#xff08;宝安&#xff09;圆满落幕。作为国内工业通信领域的技术型企业&#xff0c;光路科技&#xff08;Fiberroad&…...

在 Visual Studio Code 中使用驭码 CodeRider 提升开发效率:以冒泡排序为例

目录 前言1 插件安装与配置1.1 安装驭码 CodeRider1.2 初始配置建议 2 示例代码&#xff1a;冒泡排序3 驭码 CodeRider 功能详解3.1 功能概览3.2 代码解释功能3.3 自动注释生成3.4 逻辑修改功能3.5 单元测试自动生成3.6 代码优化建议 4 驭码的实际应用建议5 常见问题与解决建议…...

解析两阶段提交与三阶段提交的核心差异及MySQL实现方案

引言 在分布式系统的事务处理中&#xff0c;如何保障跨节点数据操作的一致性始终是核心挑战。经典的两阶段提交协议&#xff08;2PC&#xff09;通过准备阶段与提交阶段的协调机制&#xff0c;以同步决策模式确保事务原子性。其改进版本三阶段提交协议&#xff08;3PC&#xf…...