表定义如下

如果我们需要在表中查询这个树状结构,通过SQL语句,有两种查询方法:

1.通过inner自连接查询,适用于简单的结构

SELECT
*
FROM
course_category AS one
INNER JOIN course_category AS two ON two.parentid = one.id
WHERE
one.parentid = '1'
ORDER BY
one.orderby,
two.orderby

2.通过CTE(Common Table Expression)递归查询:适用于灵活的表结构:需要多层递归

首先举一个递归sql的例子

WITH recursive t1 as ( # with关键字用于定义CTE,,recursive关键字表示这是一个递归CTE
SELECT 1 as n # 递归的基础部分,
union all # 用于将两个select的结果集合并,与union不同的是他不会去重
SELECT n+1 FROM t1 where n<5
)
select * from t1

关于性能:MySQL规定默认递归次数不能超过1000次,并且可以通过设置cte_max_recursion_depth参数来增加递归深度,通过cte_max_recursion_time限制执行时间。

MySQL递归是在存储过程中执行若干次sql语句,java程序在调用方法时会与数据库仅建立一次链接来执行递归操作。因此控制好递归次数不会影响性能

什么是存储过程:一组为了完成特定功能的SQL语句集合

# 从根节点向下递归
WITH recursive t1 as (
SELECT * FROM course_category WHERE id='1' #取得了树根
union all
SELECT course_category.* FROM course_category INNER JOIN t1 on t1.id=course_category.parentid
)
SELECT * FROM t1 ORDER BY id


# 从叶子节点向上递归
WITH recursive t1 as (
SELECT * FROM course_category WHERE id='1-1-1' #取得了树根
union all
SELECT course_category.* FROM course_category INNER JOIN t1 on t1.parentid=course_category.id
)
SELECT * FROM t1 ORDER BY id

如何在java中使用:

首先除了po以外,还需要一个dto,dto需要extends po,同时内包含一个List<dto>childTreeNodes属性

service层方法:获取当前节点的所有子节点后,通过遍历所有节点,依次构造树形关系

public List<CourseCategoryTreeDto> queryTreeNodes(String id) {
List<CourseCategoryTreeDto> courseCategoryTreeDtoList = mapper.selectTreeNodes(id);

// 为了方便获取结点,封装到map中
Map<String, CourseCategoryTreeDto> map = courseCategoryTreeDtoList
.stream()
.filter(item -> !id.equals(item.getId()))
.collect(Collectors.toMap(key -> key.getId(), value -> value, (key1, key2) -> key2));

List<CourseCategoryTreeDto> list = new ArrayList<>();
// 遍历所有节点,如果是当前节点的下一级节点,加入到list中;如果不是,则找到他的父节点并在list中成为父节点的子节点
courseCategoryTreeDtoList
.stream()
.filter(item -> !id.equals(item.getId()))
.forEach(node -> {
// 如果是当前节点的下一级节点
if (node.getParentid().equals(id)) {
list.add(node);
}
// 找到当前节点相应的父节点
CourseCategoryTreeDto courseCategoryTreeParent = map.get(node.getParentid());
// 父节点可能有不存在的情况,比如根节点已经在上面过滤掉了,因此一级子节点的父节点是空的
if (courseCategoryTreeParent != null) {
// 如果父节点属性为null,需要new一下集合
if (courseCategoryTreeParent.getChildrenTreeNodes() == null) {
courseCategoryTreeParent.setChildrenTreeNodes(new ArrayList<>());
}
// 将当前节点加入到父节点的子节点中
courseCategoryTreeParent.getChildrenTreeNodes().add(node);
}
});
return list;
}

如何查询MySQL存储的树形结构,层次结构的更多相关文章

  1. Python查询Mysql时返回字典结构的代码

    Python查询Mysql时返回字典结构的代码 MySQLdb默认查询结果都是返回tuple,输出时候不是很方便,必须按照0,1这样读取,无意中在网上找到简单的修改方法,就是传递一个cursors.D ...

  2. 关于mysql中数据存储复合树形结构,查询时结果按树形结构输出

    1.主要思想:根据已有数据,规则性的造数据 select * FROM(select lId,strName,lId as lParentId,-1 as orderIdx from tbClassi ...

  3. 数据库查询,显示为树形结构(easyui+SSM)

    在实际项目上,有很多地方后台存了一个表,但是在显示查询的时候需要显示为树形结构. 本项目是easyui+SSM框架. 前台程序为: <!DOCTYPE html> <html> ...

  4. 【MySQL疑难杂症】如何将树形结构存储在数据库中(方案一、Adjacency List)

    今天来看看一个比较头疼的问题,如何在数据库中存储树形结构呢? 像mysql这样的关系型数据库,比较适合存储一些类似表格的扁平化数据,但是遇到像树形结构这样有深度的人,就很难驾驭了. 举个栗子:现在有一 ...

  5. Mysql通过Adjacency List(邻接表)存储树形结构

    转载自:https://www.jb51.net/article/130222.htm 以下内容给大家介绍了MYSQL通过Adjacency List (邻接表)来存储树形结构的过程介绍和解决办法,并 ...

  6. MySql/Oracle树形结构查询

    Oracle树形结构递归查询 在Oracle中,对于树形查询可以使用start with ... connect by select * from treeTable start with id='1 ...

  7. 「SQL归纳」树形结构表的存储与查询功能的实现——通过路径方法(非递归)

    一.树形结构例子分析: 以360问答页面为例:http://wenda.so.com/c/ 我们通过观察URL,可以明确该页面的数据以树形结构存储,下面三块模块分别为: ①根节点 ②根节点的第一层子节 ...

  8. MySql树形结构(多级菜单)查询设计方案

    背景 又很久没更新了,很幸运地新冠引发了严重的上呼吸道感染,大家羊过后注意休息和防护 工作中(尤其是传统项目中)经常遇到这种需要,就是树形结构的查询(多级查询),常见的场景有:组织架构(用户部门)查询 ...

  9. 为什么 MySQL 索引要使用 B+树而不是其它树形结构?比如 B 树?

    一个问题? InnoDB一棵B+树可以存放多少行数据?这个问题的简单回答是:约2千万 为什么是这么多呢? 因为这是可以算出来的,要搞清楚这个问题,我们先从InnoDB索引数据结构.数据组织方式说起. ...

  10. 为什么MySQL索引要使用 B+树,而不是其它树形结构?

    作者:李平 https://www.cnblogs.com/leefreeman/p/8315844.html 一个问题? InnoDB一棵B+树可以存放多少行数据?这个问题的简单回答是:约2千万 为 ...

随机推荐

  1. Windows 7 任务栏开发 之 进度条(Progress Bar)

    上一篇我们完成了"覆盖图标"(Overlay Icon)的相关开发,本篇我们将对进度条特性进行研究.在使用IE 下载文件时,任务栏图标会同步显示当前下载进度(如下图).那么在应用程 ...

  2. Flutter(五):Flutter 加入现有App的方案选择(Flutter_Boost)

    一.介绍 用 Flutter 一次性重写整个已有的应用是不切实际的.对于这些情况,Flutter 可以作为一个库或模块,集成进现有的应用当中.模块引入到您的 Android 或 iOS 应用(当前支持 ...

  3. zoxide更新后 (cd)异常

    关于zoxide github地址:https://github.com/ajeetdsouza/zoxide 简单来说 zoxide是一个cd的强化版.它会记录你曾经cd过的目录,在你使用cd的时候 ...

  4. 《python核心编程《第二版》》笔记章节索引

    本文章作为我的其它一系列关于<python核心编程<第二版>>的笔记的文章索引. 第一章:Python-快速入门:https://www.cnblogs.com/mrlayfo ...

  5. 赛博斗地主——使用大语言模型扮演Agent智能体玩牌类游戏。

    通过大模型来实现多个智能体进行游戏对局这个想对已经比较成熟了无论是去年惊艳的斯坦福小镇还是比如metaGPT或者类似的框架都是使用智能体技术让大模型来操控,从而让大模型跳出自身"预测下一个t ...

  6. 类的阐述 package(包)

    类的阐述 同一个文件中可以定义很多类 编译后,每个类都会生成独立的.class文件 一个类中,只能有一个主函数,每个类都可以有自己的主函数 public修饰的类称为公开类,要求类名必须与文件名称完全相 ...

  7. C++常用模板

    常用模板: 数学: 1. 组合数 组合数 #include<bits/stdc++.h> using namespace std; #define ll long long const l ...

  8. asp.net中gridview隐藏一列并且使用这列数据的方法

    方法一:在RowCreated事件中添加如下代码可隐藏此列,使用this.grdView.Rows[index].Cells[1].Text获取值,index为行号. 1 protected void ...

  9. Sass报错: Using / for division is deprecated

         原因是:当sass版本>= 1.33.0时,会不支持 / 这种语法:  解决方式一:      降低sass版本,将sass版本换成:"sass": "^ ...

  10. shiro有哪些组件?

    a.Authentication:身份认证/登录,验证用户是不是拥有相应的身份: b.Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限:即判断用户是否能做事情,常见的 ...