表定义如下

如果我们需要在表中查询这个树状结构,通过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. 像阿里OSS一样的文件对像存储服务,容器实现 docker初探及minio测试

    像阿里OSS一样的文件对像存储服务,容器实现 docker run -p 8000:9000 --name oss-minio -d -e "MINIO_ACCESS_KEY=AKIAIOS ...

  2. 怎么使用Stable diffusion中的models

    Stable diffusion中的models Stable diffusion model也可以叫做checkpoint model,是预先训练好的Stable diffusion权重,用于生成特 ...

  3. 7.14考试总结(NOIP模拟15)[夜莺与玫瑰·影子·玫瑰花精]

    梦总是有会醒来的时候,不会醒的梦总有一天会变成悲伤. 前言 这次考试的思维含量有一点大(此时距离考试还有 7min 而我的总结还没写完..) 但是对于以前的考试来讲还是有所进步的,毕竟在考试的时候还是 ...

  4. redux中集成immutable.js

    安装redux-immutable redux中利用combineReducers来合并reducer并初始化state,redux自带的combineReducers只支持state是原生js形式的 ...

  5. 已将此(这些)订阅标记为不活动,必须将其重新初始化。需要删除 NoSync 订阅,然后重

    已将此(这些)订阅标记为不活动,必须将其重新初始化.需要删除 NoSync 订阅,然后重 查找状态不正常的发布 use distribution go select status,*from dbo. ...

  6. edge 书签栏 收藏夹栏 字体大小

    WIN10中,edge收藏夹栏字体太大,如果收藏数目多,得多翻好几页. 解决方法: 地址栏中输入: edge://flags/#edge-pc-ui-integration Enable Window ...

  7. 暴走漫画系列之高仿淘宝收货地址(附demo)

    引语: 我是个程序猿,一天我坐在路边一边喝水一边苦苦检查bug. 这时一个乞丐在我边上坐下了,开始要饭,我觉得可怜,就给了他1块钱. 然后接着调试程序.他可能生意不好,就无聊的看看我在干什么,然后过了 ...

  8. ElasticSearch基于安装包方式安装

    1.下载地址 https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.5.4.tar.gz2.解压 tar -zxvf ...

  9. 如果redis没有设置expire,他是否默认永不过期

    如果redis没有设置expire,他是否默认永不过期?默认是的 通过EXPIRE key seconds 命令来设置数据的过期时间.返回1表明设置成功,返回0表明key不存在或者不能成功设置过期时间 ...

  10. hbase的优缺点

    一. 一个关于hbase介绍全面的博客地址 https://www.csdn.net/gather_22/MtTaEgysNjYwOS1ibG9n.html 优点: 1,方便高效的压缩数据. 2,支持 ...