用mysql存储过程代替递归查询

Posted tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用mysql存储过程代替递归查询相关的知识,希望对你有一定的参考价值。

用mysql存储过程代替递归查询

查询此表某个id=4028ab535e370cd7015e37835f52014b(公司1)下的所有数据

正常情况下,我们采用递归算法查询,如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public void findCorpcompanyListByParentId(List<UapcompanyVo> vos,String parentId){
        UapcompanyParam param = new UapcompanyParam();
        param.setParentid(parentId);
        List<Uapcompany> companyList = uapcompanyDao.finduapcompanyList(param);
        UapcompanyVo uapcompanyVo = null;
        for(Uapcompany uapcompany : companyList){
            uapcompanyVo = new UapcompanyVo();
            uapcompanyVo = new UapcompanyVo();
            uapcompanyVo.setId(uapcompany.getId());
            uapcompanyVo.setName(uapcompany.getName());
            uapcompanyVo.setParentid(uapcompany.getParentid());
            vos.add(uapcompanyVo);
            this.findCorpcompanyListByParentId(vos, uapcompany.getParentid());
        }
}

递归查询也能实现该需求,但是这样有两个缺点:一,性能很差 ,因为每递归一次至少调用一次数据链接;二,如果数据量很大的话,可能会导致溢出,当然可以修改虚拟机参数,不过这也是治标不治本的方法

接下来,我们看一下存储过程实现查询:

选择函数-->右键-->选择新建函数

选择过程

添加入参参数,如下图所示

完成,如下图所示

在begin end区域编写存储过程内容

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
BEGIN
    #声明一个flag变量,默认值为-99
    DECLARE flag INT DEFAULT -99;
     
    #创建companyTempTabl_Qurey临时表
    CREATE TEMPORARY TABLE IF NOT EXISTS companyTempTabl_Qurey (
        id VARCHAR(32) NOT NULL,
        `nameVARCHAR(100),
        attr VARCHAR(30),
        parentId VARCHAR(32)
    );
    TRUNCATE TABLE companyTempTabl_Qurey;
      #创建companyTempTabl_Result临时表
      CREATE TEMPORARY TABLE IF NOT EXISTS companyTempTabl_Result (
        id VARCHAR (32) NOT NULL,
        `nameVARCHAR (100),
        attr VARCHAR (30),
        parentId VARCHAR (32)
    );
    TRUNCATE TABLE companyTempTabl_Result;
     
    #根据参数 parentId 查询数据,并插入companyTempTabl_Qurey临时表
    INSERT INTO companyTempTabl_Qurey (
        id,
        `name`,
        attr,
        parentId
    SELECT
    uapcompany.id,
    uapcompany.`name`,
    uapcompany.attr,
    uapcompany.parentId
    FROM uapcompany
    WHERE uapcompany.parentId = `parentId`;
     
      #根据参数 parentId 查询数据,并插入companyTempTabl_Result临时表
    INSERT INTO companyTempTabl_Result (
        id,
        `name`,
        attr,
        parentId
    SELECT
    uapcompany.id,
    uapcompany.`name`,
    uapcompany.attr,
    uapcompany.parentId
    FROM uapcompany
    WHERE uapcompany.parentId = `parentId`;
     
    #根据参数 parentId 统计查询总数,并赋值给变量flag
    SELECT count(1) INTO flag
    FROM uapcompany
    WHERE uapcompany.parentId = `parentId`;
     
    #如果flag 大于 0,则进行循环
    WHILE flag > 0 DO
        #创建companyTempTabl_temp 临时表
        CREATE TEMPORARY TABLE IF NOT EXISTS companyTempTabl_temp (
            id VARCHAR (32) NOT NULL,
            `nameVARCHAR (100),
            attr VARCHAR (30),
            parentId VARCHAR (32)
        );
        TRUNCATE TABLE companyTempTabl_temp;
         
        #数据库表uapcompany关联临时表companyTempTabl_Qurey查询,并将查询结果插入 临时表companyTempTabl_temp
        INSERT INTO companyTempTabl_temp (id, `name`, attr, parentId) SELECT
            uapcompany.id,
            uapcompany.`name`,
            uapcompany.attr,
            uapcompany.parentId
        FROM
            uapcompany,
            companyTempTabl_Qurey
        WHERE
            uapcompany.parentId = companyTempTabl_Qurey.id;
         
        #删除临时表companyTempTabl_Qurey数据
        DELETE FROM companyTempTabl_Qurey;
         
        #将临时表companyTempTabl_temp的数据 插入companyTempTabl_Qurey临时表,用作下一个循环的条件
        INSERT INTO companyTempTabl_Qurey (id, `name`, attr, parentId) SELECT
            companyTempTabl_temp.id,
            companyTempTabl_temp.`name`,
            companyTempTabl_temp.attr,
            companyTempTabl_temp.parentId
        FROM
            companyTempTabl_temp;
         
        #将临时表companyTempTabl_temp的数据 插入到companyTempTabl_Result临时表(该表的数据也是我们最终要返回的数据)
        INSERT INTO companyTempTabl_Result (id, `name`, attr, parentId) SELECT
            companyTempTabl_temp.id,
            companyTempTabl_temp.`name`,
            companyTempTabl_temp.attr,
            companyTempTabl_temp.parentId
        FROM
            companyTempTabl_temp;
         
        #删除companyTempTabl_temp数据
        DROP TABLE companyTempTabl_temp;
         
        #数据库表uapcompany关联 临时表companyTempTabl_Qurey查询统计,并将结果赋值给变量flag
        SELECT
            count(1) INTO flag
        FROM
            uapcompany,
            companyTempTabl_Qurey
        WHERE
            uapcompany.parentId = companyTempTabl_Qurey.id;
    END WHILE;
    SELECT id ,`name`,attr,parentId  FROM companyTempTabl_Result;
 
END

 然后保存

测试一下,点击运行

输入参数,点击确定,结果如下图所示

我们在dao层只需要调用一次该 存储过程,就可以返回自己想要的数据,存储过程中创建的临时表随着链接的释放自动删除

 

以上是关于用mysql存储过程代替递归查询的主要内容,如果未能解决你的问题,请参考以下文章

mysql递归查询语句

mysql如何递归汇总?

求高手帮忙sql写法:树节点放一个表中,怎么用一条语句查询一个节点及对应的所有父节点信息。

怎么在mysql中查询已建立的存储过程

使用MyBatis轻松实现递归查询与存储过程调用

SQL问题 实现递归查询

(c)2006-2024 SYSTEM All Rights Reserved IT常识