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

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个使用SpringBoot实现树形结构的代码示例: 首先,我们需要定义一个树形结构的实体类,如下所示: ```java public class TreeNode { private Long id; private String name; private Long parentId; private List<TreeNode> children; // 省略getter和setter方法 } ``` 接下来,我们需要定义一个服务来获取树形结构数据,并将其转换为树形结构。这里我们使用递归算法实现转换: ```java @Service public class TreeService { @Autowired private TreeNodeMapper treeNodeMapper; public List<TreeNode> getTree() { List<TreeNode> nodeList = treeNodeMapper.findAll(); List<TreeNode> treeList = new ArrayList<>(); for (TreeNode node : nodeList) { if (node.getParentId() == null) { treeList.add(findChildren(node, nodeList)); } } return treeList; } private TreeNode findChildren(TreeNode parentNode, List<TreeNode> nodeList) { for (TreeNode node : nodeList) { if (parentNode.getId().equals(node.getParentId())) { if (parentNode.getChildren() == null) { parentNode.setChildren(new ArrayList<>()); } parentNode.getChildren().add(findChildren(node, nodeList)); } } return parentNode; } } ``` 最后,我们需要在Controller中调用服务,并返回树形结构数据: ```java @RestController public class TreeController { @Autowired private TreeService treeService; @GetMapping("/tree") public List<TreeNode> getTree() { return treeService.getTree(); } } ``` 这样,我们就可以通过访问`/tree`接口获取树形结构数据了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值