首页 > 数据库 >如何查询MySQL存储的树形结构,层次结构

如何查询MySQL存储的树形结构,层次结构

时间:2024-06-13 19:00:25浏览次数:20  
标签:category 递归 节点 course 层次结构 树形 MySQL t1 id

表定义如下

 如果我们需要在表中查询这个树状结构,通过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 courseCategoryTreeDto = map.get(node.getParentid());
                    // 父节点可能有不存在的情况,比如根节点已经在上面过滤掉了,因此一级子节点的父节点是空的
                    if (courseCategoryTreeDto != null) {
                        // 如果父节点属性为null,需要new一下集合
                        if (courseCategoryTreeDto.getChildrenTreeNodes() == null) {
                            courseCategoryTreeDto.setChildrenTreeNodes(new ArrayList<>());
                        }
                        // 将当前节点加入到父节点的子节点中
                        courseCategoryTreeDto.getChildrenTreeNodes().add(node);
                    }
                });
        return list;
    }

 

标签:category,递归,节点,course,层次结构,树形,MySQL,t1,id
From: https://www.cnblogs.com/kun1790051360/p/18246452

相关文章

  • 【java计算机毕设】图书管理系统javaweb java MySQL springboot vue html maven送文档
    1项目功能【java计算机专业学长毕业设计分享】智慧图书管理系统JavaSpringBootvueHTMLMySQL前后端分离2项目介绍系统功能:智慧图书管理系统包括管理员和用户两种角色。管理员的功能包括在个人中心修改个人信息和密码,管理员功能模块管理管理员。基础数据管理模......
  • MySQL的联合索引
    这里我先创建一张叫tb_user的表数据有创建一个联合索引  1.符合index(a,b,c)的查询条件 他的查询范围是ref使用了索引2.符合index(a,b)的查询条件  他的查询范围是ref使用了索引3.符合index(a)的查询条件   他的查询范围是ref使用了索引4.符合index(b,c......
  • MySQL 新建事件执行存储过程
    开启事件调度器SETGLOBALevent_scheduler=ON;编写事件注意:命令行会将分号【;】识别为结束符,可以使用navicat创建事件;或者使用DELIMITER关键字替换分号/*如果error_event事件存在,则先删除它*/DROPEVENTIFEXISTSerror_event;/*创建一个名为error_event的事......
  • Linux系统的mysql如何导出表数据
    在Linux系统上,我们可以使用mysqldump命令来导出MySQL数据库中的表数据。mysqldump是一个用于备份数据库的命令行工具,它可以将整个数据库或特定的表导出为SQL脚本文件,以便在其他环境中恢复或迁移数据。本文将介绍如何使用mysqldump命令导出表数据,并提供相关的代码示例和流程图。1......
  • linux 下MySQL命令行导出csv文件格式
    从数据库服务器导出1、登录mysqlmysql-uroot-p2、切换数据库usedatabase3、导出文件命令SELECTid,column1,column2FROMtableINTOOUTFILE'/tmp/mysqlfiles/table.csv'FIELDSTERMINATEDBY','ENCLOSEDBY'"'LINESTERMINATEDBY'n' sel......
  • MySQL The instance is already part of another Replication Group
    MySQLInnoDBCluster(测试环境为MySQL8.0.35)将一个实例重新加入集群时,遇到了下面这个错误"Theinstance'dbu03:3306'isalreadypartofanotherReplicationGroup"MySQL  10.160.2.55:3306 ssl  JS > cluster.addInstance('[email protected]:3306')ERROR: Ru......
  • mysql部署
    首先在mysql官网上下载mysql的软件包#useradd-r -s/bin/falsemysql#创建程序账号#tar-xfmysql-5.7.31-linux-glibc2.12-x86_64.tar.gz#解压,跟上面的命令重复了#mvmysql-5.7.31-linux-glibc2.12-x86_64/usr/local/mysql#移动#cd/usr/local/mysql/#mkdirmysq......
  • MySQL 被 PG 干翻了。。
    StackOverflow发布了2023年开发者调查报告,据称共计超过9万名开发者参与了此次调查。完整报告包含了受访开发者画像,以及关于开发技术、AI、职业、社区等方面的内容。本文主要介绍关于开发技术和AI的部分。懒人目录:最流行编程语言:JavaScript最“赚钱”编程语言......
  • MySQL周内训参照、DDL与DML语句
    根据ER图与数据库模型图设计DDL语句无注释DDLCREATETABLEuser(user_idINTAUTO_INCREMENTPRIMARYKEY,usernameVARCHAR(50)NOTNULLUNIQUE,passwordVARCHAR(255)NOTNULL,emailVARCHAR(100)UNIQUE,phoneVARCHAR(20)UNIQUE,creat......
  • MySQL 被 PG 干翻了。。
    StackOverflow发布了2023年开发者调查报告,据称共计超过9万名开发者参与了此次调查。完整报告包含了受访开发者画像,以及关于开发技术、AI、职业、社区等方面的内容。本文主要介绍关于开发技术和AI的部分。懒人目录:最流行编程语言:JavaScript最“赚钱”编程语言......