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

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

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

/*
 Navicat Premium Data Transfer

 Source Server         : mysql8.0
 Source Server Type    : MySQL
 Source Server Version : 80029 (8.0.29)
 Source Host           : localhost:3307
 Source Schema         : springboot_mybatis

 Target Server Type    : MySQL
 Target 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.Driver
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      stat-view-servlet:
        enabled: true
        login-username: 
        login-password: 
      web-stat-filter:
        enabled: true

#  sql:
#    init:
#      schema-locations: classpath:sql/schema.sql
#      mode: always
server:
  port: 8089

logging:
  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 {
    @Override
    public 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 {

    @Autowired
    private 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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/7275.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

大数据环境-云平台(阿里云)

由于电脑配置原因&#xff0c;无法在本地利用虚拟机搭建环境&#xff0c;因此使用云平台来当做学习的环境。 本节内容参考&#xff1a; 【2023新版黑马程序员大数据入门到实战教程&#xff0c;大数据开发必会的Hadoop、Hive&#xff0c;云平台实战项目全套一网打尽-哔哩哔哩】 …

72-Linux_线程同步

线程同步一.什么是线程同步二.线程同步的方法1.互斥锁(1)什么是互斥锁(2)互斥锁的接口(3)互斥锁的使用(例题)2.信号量(1)什么是信号量(2)信号量的接口(3)信号量的使用(例题)a.循环打印ABCb.:主线程获取用户输入,函数线程将用户输入的数据存储到文件中;3.读写锁(1)读写锁的接口(…

R语言|plot和par函数绘图详解,绘图区域设置 颜色设置 绘图后修改及图像输出

plot()函数 plot()函数是R中最基本的绘图函数&#xff0c;其实最简单、最基础的函数&#xff0c;这也就意味着其具有更多的可操作性。 plot(x,y,...) 在plot函数中&#xff0c;只需指定最基本的x和y轴对应数据即可进行图像的绘制&#xff0c;x和y轴数据分别为两个向量或者是只…

年薪40W测试工程师成长之路,你在哪个阶段?

对任何职业而言&#xff0c;薪资始终都会是众多追求的重要部分。前几年的软件测试行业还是一个风口&#xff0c;随着不断地转行人员以及毕业的大学生疯狂地涌入软件测试行业&#xff0c;目前软件测试行业“缺口”已经基本饱和。当然&#xff0c;我说的是最基础的功能测试的岗位…

WIN10無法再使用 IE 瀏覽器打开网页解决办法

修改 Registry&#xff08;只適用 Win10&#xff09; 微軟已於 2023 年 2 月 14 日永久停用 Internet Explorer&#xff0c;會透過 Edge 的更新讓使用者開啟 IE 時自動導向 Edge&#xff0c;其餘如工作列上的圖示&#xff0c;使用的方法則是透過「品質更新」的 B 更新來達成&am…

NoSQL与Redis五次作业回顾

文章目录1. 作业12. 作业23. 作业34. 作业45. 作业51. 作业1 要求&#xff1a; 在 VM 上安装 CentOS Linux 系统&#xff0c;并在 Linux 上通过 yum 安装 C编译器&#xff0c;对 Redis 进行编译安装。 观察 Redis 目录结构&#xff0c;使用 redis-server 启动服务器&#xff…

Android---Jetpack之DataBinding

DataBinding 的意义 让布局文件承担了部分原本属于页面的工作&#xff0c;使页面与布局耦合度进一步降低。 DataBinding 的应用 使用 dataBinding 需要在 gradle 里添加如下代码 dataBinding{enabled true} 应用实现 activity_main.xml <?xml version"1.0" e…

python argparse的使用,本文基本够用

一、前言 在学习深度学习会发现都比较爱用python这个argparse&#xff0c;虽然基本能理解&#xff0c;但没有仔细自己动手去写&#xff0c;因此这里写下来作为自己本人的学习笔记 argparse是python的一个命令行参数解析包&#xff0c;在代码需要频繁修改参数时&#xff0c;方便…

Shell编程之免交互

目录交互的概念与Linux中的运用Here Document 免交互tee命令重定向输出加标准输出支持变量替换多行注释Expect实例操作免交互预设值修改用户密码创建用户并设置密码实现 ssh 自动登录交互的概念与Linux中的运用 交互&#xff1a;当计算机播放某多媒体程序的时候&#xff0c;编…

步进频雷达的一维距离像matlab仿真

步进频雷达的一维距离像matlab仿真发射与回波信号模型距离高分辨原理仿真分析不进行步进频高分辨一维距离像进行步进频高分辨一维距离像代码发射与回波信号模型 步进频率信号发射得的是一串窄带的相参脉冲&#xff0c;每个脉冲的载频之间是均匀线性步进的&#xff0c;经过相参本…

Spring依赖注入详解

1.set注入 启动容器后看看到底能不能拿到teacherService的值。可以看到拿到了值。我们具体来分析怎么注入的 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean 发现pvs里面有一个我们自己set的值 直接进行属性赋值。 org.springf…

【创作赢红包】Python第3章 流程控制

这里写目录标题【本章导读】真值测试比较运算成员运算for循环while循环项目实训1项目实训2项目实训3项目实训4&#xff1a;项目实训5&#xff1a;项目实训6&#xff1a;项目实训7&#xff1a;项目实训8项目实训9&#xff1a;项目实训10:项目实训11&#xff1a;项目实训12&#…

【Redis7】Redis7 十大数据类型

【大家好&#xff0c;我是爱干饭的猿&#xff0c;本文重点介绍Redis7 十大数据类型。 后续会继续分享Redis7和其他重要知识点总结&#xff0c;如果喜欢这篇文章&#xff0c;点个赞&#x1f44d;&#xff0c;关注一下吧】 上一篇文章&#xff1a;《【Redis7】Redis7概述、安装…

PCB生产工艺流程五:PCB生产工艺流程的第3步,钻孔的分类及目的

PCB生产工艺流程五&#xff1a;PCB生产工艺流程的第3步&#xff0c;钻孔的分类及目的 今天第五期的内容就是详细讲述PCB工艺流程第三步——钻孔&#xff0c;忘记第二步的小伙伴看这里 PCB工艺流程第2步&#xff0c;你了解多少&#xff1f; 钻孔的目的 在板面上钻出层与层之间…

【Java项目】SpringBoot实现一个请求同时上传多个文件和类并附上代码实例

文章目录前言文件多线程兼多文件上传RequestParam和RequestPart的区别前言 项目在做二手市场&#xff0c;然后商品的提交我们希望对商品的描述和商品的照片能一起传递到同一个接口来统一处理&#xff0c;而不是分发到两个接口中去处理&#xff0c;因为如果分到两个接口那么会特…

大语言模型带来的一些启发

仅代表个人看法&#xff0c;不喜勿喷。 The limits of my language means the limits of my world. (Ludwig Wittgenstein) 我的语言的极限意味着我的世界的极限。——维特根斯坦 大语言模型解决的不仅是处理文本相关问题&#xff0c;它带来的是人对世界的理解&#xff0c;或者…

华为网络篇 单臂路由-17

实验难度 2实验复杂度2目录 一、实验原理 二、实验拓扑 三、实验步骤 四、实验过程 总结 一、实验原理 单臂路由&#xff08;router-on-a-stick&#xff09;是指在路由器的一个接口上通过配置子接口&#xff08;或“逻辑接口”&#xff0c;并不存在真正物理接口&…

EasyExcel的简单使用(easyExcel和poi)

EasyExcel的简单使用 前言 Excel读 1.实体类 2.读监听器与测试类 3.输出结果 Excel写 1.实体类 2.写入Excel的测试类 3.输出结果 填充Excel 1.Excel模板 2.测试类 3.输出结果 前言 EasyExcel类是一套基于Java的开源Excel解析工具类&#xff0c;相较于传统的框架如Apache poi、…

Go 语言数组和切片的区别

原文链接&#xff1a; Go 语言数组和切片的区别 在 Go 语言中&#xff0c;数组和切片看起来很像&#xff0c;但其实它们又有很多的不同之处&#xff0c;这篇文章就来说说它们到底有哪些不同。 另外&#xff0c;这个问题在面试中也经常会被问到&#xff0c;属于入门级题目&…

堆及其堆排序

堆是一种特殊的数据结构&#xff0c;底层实现是靠数组存储以及完全二叉树的性质 文章目录一、堆概念二、堆实现三、堆源码四、堆排序一、堆概念 完全二叉树用数组来存储可以达到空间的有效利用且可以直观反映它们之间的逻辑关系&#xff0c;双亲与孩子之间的关系。一般在数组中…