MySQL高效查询某节点下的所有子节点

MySQL不是T-SQL,没有cte,那么要查询子节点就会比较麻烦,需要在程序中使用到递归查询。

比较好的做法是,在建表的时候,就要考虑到此问题,需要有一个存节点层级信息的字段,比如这样:

image_1c0qs8ph1s6tgtq57pat011459.png-39.7kB

设置方法为:

public int insert(Organization organization) {
    NumberFormat num = getNumberInstance();
    num.setGroupingUsed(false);
    num.setMinimumIntegerDigits(3);
    //设置code
    if(organization.getParentId()!=null){   //子节点
        //获取父节点的code
        String parentCode = organizationMapper.findCodeById(organization.getParentId());
        //根据父节点的code,获取当前地区编号的最大值
        String maxCodeByDivisionCode = organizationMapper.findMaxCodeByDivisionCode(parentCode);
        if(maxCodeByDivisionCode.equals(parentCode)){
            organization.setCode(maxCodeByDivisionCode + "001");
        }else{
            //地区编号最大值+1
            int code = Integer.parseInt(maxCodeByDivisionCode.substring(maxCodeByDivisionCode.length() - 3, maxCodeByDivisionCode.length()))+1;
            organization.setCode(maxCodeByDivisionCode.substring(0,maxCodeByDivisionCode.length()-3)+num.format(code));
        }
    }else{  //顶级节点
        //根据当前节点code,获取当前地区编号的最大值
        String maxCodeByDivisionCode = organizationMapper.findMaxCodeByDivisionCode(organization.getDivisionCode());
        if(maxCodeByDivisionCode!=null){
            int code = Integer.parseInt(maxCodeByDivisionCode.substring(maxCodeByDivisionCode.length() - 3, maxCodeByDivisionCode.length()))+1;
            organization.setCode(maxCodeByDivisionCode.substring(0,maxCodeByDivisionCode.length()-3)+num.format(code));
        }else{
            organization.setCode(maxCodeByDivisionCode + "001");
        }
    }
    return this.organizationMapper.insert(organization);
}

这么设计的好处是:

  1. 你可以根据任何一个节点来找他下面所有的子节点及子节点下的子节点,like一下就出来了;
  2. 可以根据任何一个子节点来找他上级节点,上级的上级,直到顶级节点,只需根据这个字段拆分下就行而不需要做数据库查询。

另外,我这里的 divisionCode 是地区编号,且是新增时的必选字段。

原文地址:https://www.cnblogs.com/VitoYi/p/8006826.html