首页 > 数据库 >Java优化递归查询Mysql节点树数据

Java优化递归查询Mysql节点树数据

时间:2023-07-14 14:26:17浏览次数:49  
标签:... task Java 递归 map list 110 Mysql id

示例

目前有一个功能:任务计划管理,必然存在多级子任务的父子级关系,每个任务还会存在其它数据的关联表。

mysql无法一次性递归查出想要的数据结构,想必很多人都会是通过根目录递归查询数据库的方式查出树结构数据。如果节点数较多,就会造成大量请求Mysql查询,效率会很低。

那么如何优化节点树数据查询效率???

表设计

# task(任务主表) [id,name,...]
[110,"XXX项目排期",...]

# task_tree(节点树子任务表) [id,task_id,parent_id,task_name,level,task_num,...]
[1, 110, 110, "XXX项目排期",  0, 0, ...]
[2, 110, 1, "一级主任务1",     1, 1, ...]
[5, 110, 2, "二级子任务1.1",   2, 1, ...]
[6, 110, 2, "二级子任务1.2",   2, 2, ...]
[3, 110, 1, "一级主任务2",     1, 2, ...]
[4, 110, 1, "一级主任务3",     1, 3, ...]
[7, 110, 4, "二级子任务3.1",   2, 1, ...]
[8, 110, 7, "三级子任务3.1.1", 3, 1, ...]
[8, 110, 7, "三级子任务3.1.2", 3, 2, ...]

# task_tree_pre(前置任务表) 关联节点任务表 [id,task_id,task_tree_id,val,...]
# 同时关联任务主表的好处是在删除数据的时候减少不必要的关联查询
[1, 110, 6 , "2SF", ...]
[1, 110, 6 , "7SS", ...]

Java使用Map处理

原理:仅发起一次sql请求把所需数据全查出来,使用Map进行逻辑封装处理,效率非常之快。

public class Test {
    /**
     * 根据主表id查询节点树子任务数据
     */
    public TaskTree tree(String id)
    {
        TaskTree tree = new TaskTree();
        // 根据主表id查询所有的前置任务
        List<TaskTreePre> listPre = "select * from task_tree_pre where task_id = 110";
        Map<String, List<TaskTreePre>> mapPre = new HashMap<>();
        for (TaskTreePre pre : listPre) {
            // 对所有taskTreeId用map封装对应的前置任务列表
            List<TaskTreePre> list = new ArrayList<>();
            if (mapPre.containsKey(pre.getTaskTreeId())) {
                // 先获取到map中已存在的listPre,再继续添加
                list = mapPre.get(pre.getTaskTreeId());
            }
            list.add(pre);
            mapPre.put(pre.getTaskTreeId(), list);
        }
        // 根据主表id查询所有的节点树任务数据
        List<TaskTree> listTree = "select * from task_tree where task_id = 110";
        Map<String, List<TaskTree>> map = new HashMap<>();
        // 设置前置任务
        for (TaskTree task : listTree) {
            if (id.equals(task.getParentId())) {
                // 获取根节点对象
                tree = task;
            }
            // 根据任务表id获取前置任务并添加
            task.setTaskTreePreList(mapPre.get(task.getId()));
            // 对所有parentId用map封装所属的子级任务
            List<TaskTree> list = new ArrayList<>();
            if (map.containsKey(task.getParentId())) {
                list = map.get(task.getParentId());
            }
            list.add(task);
            map.put(task.getParentId(), list);
        }
        // 递归封装节点树结构数据
        tree.setChildren(initTree(map, tree.getId()));
        return tree;
    }

    /**
     * 递归封装节点树结构数据
     * @param map   key包含了所有的parentId, value=所属子级列表
     * @param id    父级id
     * @return
     */
    public List<TaskTree> initTree(Map<String, List<TaskTree>> map, String id) {
        List<TaskTree> list = new ArrayList<>();
        if (map.containsKey(id)) {
            list = map.get(id);
            if (list.size() > 0) {
                for (TaskTree task : list) {
                    task.setChildren(initTree(map, task.getId()));
                }
            }
        }
        return list;
    }
}

标签:...,task,Java,递归,map,list,110,Mysql,id
From: https://www.cnblogs.com/zhaojinhui/p/17553557.html

相关文章

  • JAVA设计模式之责任链模式
    设计模式设计模式(DesignPattern)是前辈们对代码开发经验的总结,是解决特定问题的一系列套路。它不是语法规定,而是一套用来提高代码可复用性、可维护性、可读性、稳健性以及安全性的解决方案。总体来说设计模式分为三大类:创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、......
  • 微擎开发使用workerman时,使用微擎pdo_xxx提示MySQL server has gone away解决办法
    微擎开发使用workerman时,使用微擎pdo_xxx提示MySQLserverhasgoneaway解决办法#找到微擎的DB类ramework\class\db.class.phppublicfunctionreConnect($errorInfo,$params){ if(in_array($errorInfo[1],array(1317,2013))){ $this->pdo=null; $this->conne......
  • java 抛出异常后继续执行
    Java抛出异常后继续执行的实现方法作为一名经验丰富的开发者,我将为你介绍如何在Java中实现“抛出异常后继续执行”的方法。在实现之前,我们先来了解一下整个过程的流程,然后逐步进行实现。整体流程步骤描述步骤1执行可能会抛出异常的代码步骤2捕获并处理异常......
  • java 判断字符串内容是utf-8还是utf8mb4
    判断字符串内容是UTF-8还是UTF8MB4的方法概述在Java中,判断字符串内容是UTF-8还是UTF8MB4可以通过检查字符编码范围来实现。UTF-8使用1到4个字节表示一个字符,而UTF8MB4使用1到4个字节表示一个字符。下面将介绍整个流程和每一步需要做的事情。流程步骤描述1.将字符串转......
  • java 判断以逗号分割的字符串
    Java判断以逗号分割的字符串简介在Java中,判断以逗号分割的字符串可以使用split方法将字符串分割成多个子字符串,然后逐个判断每个子字符串是否满足特定条件。本文将介绍如何使用Java实现这一功能。流程图步骤描述步骤1通过split方法将字符串分割成多个子字符串步......
  • java 判断一个对象中是否存在重复的字段
    Java判断一个对象中是否存在重复的字段1.流程以下是判断一个对象中是否存在重复字段的流程:步骤描述1获取对象的所有字段2遍历字段,将字段名存入一个集合3判断集合的大小与字段数是否相等,若不相等则存在重复字段2.代码实现下面是每个步骤所需要完成的代......
  • java 判断形状区域重叠
    Java判断形状区域重叠在计算机图形学和计算机视觉领域,判断两个形状区域是否重叠是一个常见的问题。在本文中,我们将介绍如何使用Java编程语言来判断两个形状区域是否发生重叠,以及如何实现这个功能的代码示例。什么是形状区域重叠?形状区域重叠是指两个形状区域在二维平面上发生......
  • java 判断手机号
    Java判断手机号的实现方法作为一名经验丰富的开发者,我将教会你如何使用Java来判断手机号。下面是整个实现的步骤和所需代码的详细说明。实现步骤步骤操作1获取用户输入的手机号2使用正则表达式验证手机号格式3判断手机号的长度4判断手机号的前缀是否正确......
  • java 判断时分
    Java判断时分Java是一种广泛使用的编程语言,它提供了丰富的API和工具,可以用于开发各种类型的应用程序。在Java中,我们可以使用日期和时间类来处理日期和时间的相关操作。本文将介绍如何使用Java来判断给定时间的小时和分钟。获取当前时间在Java中,我们可以使用java.util.Date类来获......
  • java8xiazai
    Java8下载文件在Java8中,文件下载是一个常见的任务。无论是从互联网下载文件还是从本地服务器下载文件,Java8都提供了一些强大的功能来处理这些任务。本文将介绍如何使用Java8来下载文件,并提供一些示例代码来帮助您更好地理解。使用URLConnection下载文件URLConnection是Java......