SpringBoot获取树状结构数据-SQL处理
前言
在开发中,层级数据(树状结构)的获取往往可能是我们一大难点,我现在将自己获取的树状结构数据方法总结如下,希望能给有需要的小伙伴有所帮助!
一、测试数据准备
/*
Navicat Premium Data Transfer Source Server : 本地MySQL-local
Source Server Type : MySQL
Source Server Version : 80100
Source Host : localhost:33306
Source Schema : test Target Server Type : MySQL
Target Server Version : 80100
File Encoding : 65001 Date: 06/09/2023 11:21:45
*/ SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0; -- ----------------------------
-- Table structure for region
-- ----------------------------
DROP TABLE IF EXISTS `region`;
CREATE TABLE `region` (
`id` bigint(0) NOT NULL COMMENT '主键id',
`region_id` bigint(0) NULL DEFAULT NULL COMMENT '区域id',
`region_code` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '区域编码',
`region_name` varchar(250) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '区域名称',
`parent_id` bigint(0) NULL DEFAULT NULL COMMENT '父节点id',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `region_id`(`region_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '地区信息' ROW_FORMAT = Dynamic; -- ----------------------------
-- Records of region
-- ----------------------------
INSERT INTO `region` VALUES (1, 10001, 'CODEA0001', '中国', 0);
INSERT INTO `region` VALUES (2, 10002, 'CODEB0001', '安徽省', 10001);
INSERT INTO `region` VALUES (3, 10003, 'CODEB0002', '黑龙江省', 10001);
INSERT INTO `region` VALUES (4, 10004, 'CODEB0003', '广东省', 10001);
INSERT INTO `region` VALUES (5, 10005, 'CODEC0001', '合肥市', 10002);
INSERT INTO `region` VALUES (6, 10006, 'CODEC0002', '淮北市', 10002);
INSERT INTO `region` VALUES (7, 10007, 'CODEC0003', '哈尔滨市', 10003);
INSERT INTO `region` VALUES (8, 10008, 'CODEC0004', '鹤岗市', 10003);
INSERT INTO `region` VALUES (9, 10009, 'CODEC0005', '广州市', 10004);
INSERT INTO `region` VALUES (10, 10010, 'CODEC0006', '深圳市', 10004);
INSERT INTO `region` VALUES (11, 10011, 'CODED0001', '龙华区', 10010);
INSERT INTO `region` VALUES (12, 10012, 'CODED0002', '南山区', 10010);
INSERT INTO `region` VALUES (13, 10013, 'CODED0003', '天河区', 10009); SET FOREIGN_KEY_CHECKS = 1;
二、对应表数据java实体类
import lombok.Data;
import java.util.List; /**
* @Project
* @Description
* @Author songwp
* @Date 2023/9/5 15:16
**/
@Data
public class Region{
private Long id;
private Long regionId;
private String regionCode;
private String regionName;
private Long parentId;
private List<Region> children; }
三、对应mapper的调用方法
import com.songwp.pojo.entity.Region;
import org.apache.ibatis.annotations.Mapper;
import java.util.List; /**
* @Project
* @Description 在 持久层,我们只调用getNodeTree方法,parent_id = 0代表顶级节点。然后通过 collection 节点继续调用getNextNodeTree方法进行循环调用。
* @Author songwp
* @Date 2023/9/5 15:22
**/
@Mapper
public interface RegionMapper { List<Region> getNodeTree();
}
四、对应mapper.xml的写法(重点)
- column 代表会拿父节点 id ,作为参数获取 next 对象
- javaType 代表 next 对象是个列表,其实可以省略不写
- ofType 用来区分 JavaBean 属性类型和集合包含的类型
- select 是用来执行循环哪个 SQL
<?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.songwp.mapper.RegionMapper"> <sql id="Base_Column_List">
id,
region_id,
parent_id,
region_code,
region_name
</sql> <resultMap id="BaseTreeResultMap" type="com.songwp.pojo.entity.Region">
<result property="id" column="id" jdbcType="BIGINT"/>
<result property="regionId" column="region_id" jdbcType="BIGINT"/>
<result property="regionCode" column="region_code" jdbcType="VARCHAR"/>
<result property="regionName" column="region_name" jdbcType="VARCHAR"/>
<result property="parentId" column="parent_id" jdbcType="BIGINT"/>
<collection column="region_id" property="children" javaType="java.util.ArrayList"
ofType="com.songwp.pojo.entity.Region" select="getNextNodeTree"/>
</resultMap> <resultMap id="NextTreeResultMap" type="com.songwp.pojo.entity.Region">
<result property="id" column="id" jdbcType="BIGINT"/>
<result property="regionId" column="region_id" jdbcType="BIGINT"/>
<result property="regionCode" column="region_code" jdbcType="VARCHAR"/>
<result property="regionName" column="region_name" jdbcType="VARCHAR"/>
<result property="parentId" column="parent_id" jdbcType="BIGINT"/>
<collection column="region_id" property="children" javaType="java.util.ArrayList"
ofType="com.songwp.pojo.entity.Region" select="getNextNodeTree"/>
</resultMap> <select id="getNextNodeTree" resultMap="NextTreeResultMap">
SELECT
<include refid="Base_Column_List"/>
FROM region
WHERE parent_id = #{id}
</select> <select id="getNodeTree" resultMap="BaseTreeResultMap">
SELECT
<include refid="Base_Column_List"/>
FROM region
WHERE parent_id = 0000
</select>
</mapper>
五、具体调用结果如下:
[
{
"id": 1,
"regionId": 10001,
"regionCode": "CODEA0001",
"regionName": "中国",
"parentId": 0,
"children": [
{
"id": 2,
"regionId": 10002,
"regionCode": "CODEB0001",
"regionName": "安徽省",
"parentId": 10001,
"children": [
{
"id": 5,
"regionId": 10005,
"regionCode": "CODEC0001",
"regionName": "合肥市",
"parentId": 10002,
"children": []
},
{
"id": 6,
"regionId": 10006,
"regionCode": "CODEC0002",
"regionName": "淮北市",
"parentId": 10002,
"children": []
}
]
},
{
"id": 3,
"regionId": 10003,
"regionCode": "CODEB0002",
"regionName": "黑龙江省",
"parentId": 10001,
"children": [
{
"id": 7,
"regionId": 10007,
"regionCode": "CODEC0003",
"regionName": "哈尔滨市",
"parentId": 10003,
"children": []
},
{
"id": 8,
"regionId": 10008,
"regionCode": "CODEC0004",
"regionName": "鹤岗市",
"parentId": 10003,
"children": []
}
]
},
{
"id": 4,
"regionId": 10004,
"regionCode": "CODEB0003",
"regionName": "广东省",
"parentId": 10001,
"children": [
{
"id": 9,
"regionId": 10009,
"regionCode": "CODEC0005",
"regionName": "广州市",
"parentId": 10004,
"children": [
{
"id": 13,
"regionId": 10013,
"regionCode": "CODED0003",
"regionName": "天河区",
"parentId": 10009,
"children": []
}
]
},
{
"id": 10,
"regionId": 10010,
"regionCode": "CODEC0006",
"regionName": "深圳市",
"parentId": 10004,
"children": [
{
"id": 11,
"regionId": 10011,
"regionCode": "CODED0001",
"regionName": "龙华区",
"parentId": 10010,
"children": []
},
{
"id": 12,
"regionId": 10012,
"regionCode": "CODED0002",
"regionName": "南山区",
"parentId": 10010,
"children": []
}
]
}
]
}
]
}
]
SpringBoot获取树状结构数据-SQL处理的更多相关文章
- selenium如何操作页面树状列表
selenium如何操作页面树状列表??举个例子:我要怎么操作如下图所示的树状结构列表?我要对这个树状结构列表做什么操作? 一.思路 1.根据driver.find_element_by_xpath( ...
- PHP利用递归法获取多级类别的树状数组
数据结构:category(id, pid, name),对应:信息ID,父项ID,类别名 测试数据: $aryCate = array( array('id' => 1, 'pid' => ...
- 根据租户id获取部门树状结构有父子结构的数据list
/** * 根据租户id获取部门树状结构 * @param tenantId * @return */ @GetMapping("getDeptTreeList") public ...
- oracle 树状结构递归 PL/SQL输出控制 包括空格输出控制
树状结构 存储过程中通过递归构建,类似BBS回帖显示,代码共三段: 建表,插入数据,创建存储过程显示: 1.create table article(id number primary key,con ...
- 菜鸟笔记:node.js+mysql中将JSON数据构建为树(递归制作树状菜单数据接口)
初学Web端开发,今天是第一次将所学做随笔记录,肯定存在多处欠妥,望大家海涵:若有不足,望大家批评指正. 进实验室后分配到的第一个项目,需要制作一个不确定层级树形菜单的数据接口,对于从来没实战编过程的 ...
- 浅谈oracle树状结构层级查询之start with ....connect by prior、level及order by
浅谈oracle树状结构层级查询 oracle树状结构查询即层次递归查询,是sql语句经常用到的,在实际开发中组织结构实现及其层次化实现功能也是经常遇到的,虽然我是一个java程序开发者,我一直觉得只 ...
- C# 递归构造树状数据结构(泛型),如何构造?如何查询?
十年河东,十年河西,莫欺少年穷. 学无止境,精益求精 难得有清闲的一上午,索性写篇博客. 首先,我们需要准备一张表,如下范例: create table TreeTable ( TreeId ) no ...
- MySQL递归查询树状表的子节点、父节点具体实现
mysql版本(5.5.6等等)尚未支持循环递归查询,和sqlserver.oracle相比,mysql难于在树状表中层层遍历的子节点.本程序重点参考了下面的资料,写了两个sql存储过程,子节点查询算 ...
- jquery-treegrid树状表格的使用(.Net平台)
上一篇介绍了DataTable,这一篇在DT的基础之上再使用jquery的一款插件:treegrid,官网地址:http://maxazan.github.io/jquery-treegrid/ 一. ...
- D3树状图异步按需加载数据
D3.js这个绘图工具,功能强大不必多说,完全一个Data Driven Document的绘图工具,用户可以按照自己的数据以及希望实现的图形,随心所欲的绘图. 图形绘制,D3默认采用的是异步加载,但 ...
随机推荐
- .NET 创建无边框的跨平台应用
.NET 创建无边框的跨平台应用 在创建了Photino应用程序以后我们发现它自带了一个标题栏,并且非常丑,我们现在要做的就是去掉这个很丑的自带标题栏,并且自定义一个更好看的,下面我们将用Masa B ...
- C# 客户端程序 Visual Studio 远程调试方法
传统桌面客户端的远程调试相比UWP,ASP等项目来说,配置比较麻烦,因为它是非部署的应用程序,原理是复制编译的文件到远程计算机,通过网络来连接和VS的通信,本文主要讲述WPF,WinForm应用程序的 ...
- 使用脚本收发 protobuf 协议数据
问题背景 最近做了一个 ipv6 相关的功能,发现使用 getifaddrs 获取的本地 ipv6 地址有可能不是真实的网络 ipv6 地址: 例如上图中通过 getifaddrs 获得了多个本地 i ...
- STM32F429 Discovery开发板应用:实现SPI-SD Card文件写入(搭载FatFS文件系统)
MCU:STM32F429ZIT6 开发环境:STM32CubeMX+MDK5 外购了一个SPI接口的SD Card模块,想要实现SD卡存储数据的功能. 首先需要打开STM32CubeMX工具.输入开 ...
- 一次性掌握innodb引擎如何解决幻读和不可重复读
了解mysql的都知道,在mysql的RR(可重复)隔离级别下解决了幻读和不可重复.你知道RR下是怎么解决的吗,很多人会回答是通过MVCC和next-key解决的,具体是怎么解决的,今天来重点分析下. ...
- 自然语言处理 Paddle NLP - 检索式文本问答-理论
问答系统(Question Answering System,QA) 是信息检索系统的一种高级形式,它能用准确.简洁的自然语言回答用户用自然语言提出的问题.其研究兴起的主要原因是人们对快速.准确地获取 ...
- 从GaussDB(DWS)的技术演进,看数据仓库的积淀与新生
摘要:随着云计算的兴起和渗透,云数仓成为了数仓技术演进的新阶段,并且逐渐成为了众多企业的共同选择. 本文分享自华为云社区<从GaussDB(DWS)的技术演进,看数据仓库的积淀与新生>,作 ...
- 在行情一般的情况下,就说说23级应届生如何找java工作
Java应届生找工作,不能单靠背面试题,更不能在简历中堆砌和找工作关系不大的校园实践经历,而是更要在面试中能证明自己的java相关商业项目经验.其实不少应届生Java求职者不是说没真实Java项目经验 ...
- 从零玩转系列之SpringBoot3-核心原理
一.简介 1.前置知识 ● Java17 ● Spring.SpringMVC.MyBatis ● Maven.IDEA 2.环境要求 环境&工具 版本(or later) SpringBoo ...
- CMU15-445 Project4 Concurrency Control心得
一.概述 过瘾!过瘾!过瘾!P4 真过瘾!写 P3 的博客时我说过"感觉自己在数据库方面真正成长了",但写完 P4 之后最大的感受就是,我终于理解了 andy 在第一课说过的&qu ...