• 用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层只需要调用一次该 存储过程,就可以返回自己想要的数据,存储过程中创建的临时表随着链接的释放自动删除

  • 相关阅读:
    js实现金额千分位显示
    iview中select组件使用总结
    在VUE中使用QRCode.js
    vue echart使用总结
    Iview Table组件中各种组件扩展
    前端架构模式Mvc和Mvvm
    express 中间件
    http与https的区别
    前后端分离与不分离的区别,两者的优势
    TCP三次握手、四次挥手
  • 原文地址:https://www.cnblogs.com/wangjintao-0623/p/10086893.html
Copyright © 2020-2023  润新知