可用这个例子进行测试递归无限下级,但是要考虑
可能会内存溢出:如果一个人有100代的下级,下级总共有20W怎么办?
如果是有这种情况的话,就不要递归无限下级了,就一级一级的找就行了,而不是一次性递归所有。
或者网友们有其他方案的话,可以评论留言指点,谢谢!
代码:
public static class LeJiHe{
private Lele;
private Listchildren;
public LegetLe() {
return le;
}
public void setLe(Le le) {
this.le = le;
}
public ListgetChildren() {
return children;
}
public void setChildren(List children) {
this.children = children;
}
}
public static class Le{
//等级 0 会员1 vip 2 svip
private Integerpin;
//会员编号
private StringdistNo;
//上级编号
private StringsponsorNo;
//名称
private StringdistName;
public IntegergetPin() {
return pin;
}
public void setPin(Integer pin) {
this.pin = pin;
}
public StringgetDistNo() {
return distNo;
}
public void setDistNo(String distNo) {
this.distNo = distNo;
}
public StringgetSponsorNo() {
return sponsorNo;
}
public void setSponsorNo(String sponsorNo) {
this.sponsorNo = sponsorNo;
}
public StringgetDistName() {
return distName;
}
public void setDistName(String distName) {
this.distName = distName;
}
}
static class XTreeKit {
public static ListformatTree(List LeList) {
List menuList =new ArrayList();
Le m0=new Le();
m0.setDistNo("003");
m0.setSponsorNo("001");
m0.setPin(1);
m0.setDistName("中山市");
LeJiHe grid =getXTreeGrid(m0, LeList);
menuList.add(grid);
return menuList;
}
/**
* 递归查找子菜单
*/
public static ListgetChild(String id, List rootMenu) {
List childList =new ArrayList();
for (Le root : rootMenu) {
// 遍历所有节点,将父菜单编码与传过来的编码进行比较、若相同则继续查看该节点下是否还有子节点
if (!StringUtils.isEmpty(root.getSponsorNo())) {
if (root.getSponsorNo().equals(id)) {
LeJiHe grid =getXTreeGrid(root, rootMenu);
childList.add(grid);
}
}
}
return childList;
}
//构建 XTreeGrid(实体对象)
public static LeJiHegetXTreeGrid(Le ps, List permissions){
LeJiHe x =new LeJiHe();
x.setLe(ps);
x.setChildren(getChild(ps.getDistNo(),permissions)); //递增遍历所有子节点(无限层级)
return x;
}
}
public static void main(String[] args) {
Le m1=new Le();
m1.setDistNo("006");
m1.setSponsorNo("003");
m1.setPin(2);
m1.setDistName("东区");
Le m2=new Le();
m2.setDistNo("007");
m2.setSponsorNo("003");
m2.setPin(1);
m2.setDistName("石岐区");
Le m3=new Le();
m3.setDistNo("008");
m3.setSponsorNo("006");
m3.setPin(0);
m3.setDistName("东区一街");
Le m4=new Le();
m4.setDistNo("009");
m4.setSponsorNo("006");
m4.setPin(1);
m4.setDistName("东区二街");
Le m5=new Le();
m5.setDistNo("010");
m5.setSponsorNo("007");
m5.setPin(1);
m5.setDistName("石歧一街");
Le m6=new Le();
m6.setDistNo("011");
m6.setSponsorNo("007");
m6.setPin(2);
m6.setDistName("石歧二街");
Le m7=new Le();
m7.setDistNo("012");
m7.setSponsorNo("008");
m7.setPin(0);
m7.setDistName("东区一街广场");
Le m8=new Le();
m8.setDistNo("013");
m8.setSponsorNo("008");
m8.setPin(0);
m8.setDistName("东区一街大堂");
Le m9=new Le();
m9.setDistNo("014");
m9.setSponsorNo("009");
m9.setPin(0);
m9.setDistName("东区二街广场");
List leList=new ArrayList();
leList.add(m1);
leList.add(m2);
leList.add(m3);
leList.add(m4);
leList.add(m5);
leList.add(m6);
leList.add(m7);
leList.add(m8);
leList.add(m9);
List grid = XTreeKit.formatTree(leList);
Map map =new HashMap();
map.put("code",200);
map.put("msg","查询成功");
map.put("content",grid);
String jsonString = JSON.toJSONString(map);
System.out.println("jsonString:" + jsonString);
}
控制台输出:
jsonString:{"msg":"查询成功","code":200,"content":[{"children":[{"children":[{"children":[{"children":[],"le":{"distName":"东区一街广场","distNo":"012","pin":0,"sponsorNo":"008"}},{"children":[],"le":{"distName":"东区一街大堂","distNo":"013","pin":0,"sponsorNo":"008"}}],"le":{"distName":"东区一街","distNo":"008","pin":0,"sponsorNo":"006"}},{"children":[{"children":[],"le":{"distName":"东区二街广场","distNo":"014","pin":0,"sponsorNo":"009"}}],"le":{"distName":"东区二街","distNo":"009","pin":1,"sponsorNo":"006"}}],"le":{"distName":"东区","distNo":"006","pin":2,"sponsorNo":"003"}},{"children":[{"children":[],"le":{"distName":"石歧一街","distNo":"010","pin":1,"sponsorNo":"007"}},{"children":[],"le":{"distName":"石歧二街","distNo":"011","pin":2,"sponsorNo":"007"}}],"le":{"distName":"石岐区","distNo":"007","pin":1,"sponsorNo":"003"}}],"le":{"distName":"中山市","distNo":"003","pin":1,"sponsorNo":"001"}}]}
格式化后:
{
"msg": "查询成功",
"code": 200,
"content": [{
"children": [{
"children": [{
"children": [{
"children": [],
"le": {
"distName": "东区一街广场",
"distNo": "012",
"pin": 0,
"sponsorNo": "008"
}
}, {
"children": [],
"le": {
"distName": "东区一街大堂",
"distNo": "013",
"pin": 0,
"sponsorNo": "008"
}
}],
"le": {
"distName": "东区一街",
"distNo": "008",
"pin": 0,
"sponsorNo": "006"
}
}, {
"children": [{
"children": [],
"le": {
"distName": "东区二街广场",
"distNo": "014",
"pin": 0,
"sponsorNo": "009"
}
}],
"le": {
"distName": "东区二街",
"distNo": "009",
"pin": 1,
"sponsorNo": "006"
}
}],
"le": {
"distName": "东区",
"distNo": "006",
"pin": 2,
"sponsorNo": "003"
}
}, {
"children": [{
"children": [],
"le": {
"distName": "石歧一街",
"distNo": "010",
"pin": 1,
"sponsorNo": "007"
}
}, {
"children": [],
"le": {
"distName": "石歧二街",
"distNo": "011",
"pin": 2,
"sponsorNo": "007"
}
}],
"le": {
"distName": "石岐区",
"distNo": "007",
"pin": 1,
"sponsorNo": "003"
}
}],
"le": {
"distName": "中山市",
"distNo": "003",
"pin": 1,
"sponsorNo": "001"
}
}]
}
上面只是测试类,可以直接运行,没有从数据库里面查询出来,可以到时在代码自己改。
建表和表数据sql:
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for tb
-- ----------------------------
DROP TABLE IF EXISTS `tb`;
CREATE TABLE `tb` (
`dist_no` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
`sponsorNo` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
`pin` int(2) DEFAULT NULL,
`dist_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of tb
-- ----------------------------
INSERT INTO `tb` VALUES ('000', NULL, 2, '中国');
INSERT INTO `tb` VALUES ('001', '000', 2, '广东省');
INSERT INTO `tb` VALUES ('002', '001', 2, '广州市');
INSERT INTO `tb` VALUES ('003', '001', 1, '中山市');
INSERT INTO `tb` VALUES ('004', '002', 1, '天河区');
INSERT INTO `tb` VALUES ('005', '002', 1, '海珠区');
INSERT INTO `tb` VALUES ('006', '003', 2, '东区');
INSERT INTO `tb` VALUES ('007', '003', 1, '石岐区');
INSERT INTO `tb` VALUES ('008', '006', 0, '东区一街');
INSERT INTO `tb` VALUES ('009', '006', 1, '东区二街');
INSERT INTO `tb` VALUES ('010', '007', 1, '石歧一街');
INSERT INTO `tb` VALUES ('011', '007', 2, '石歧二街');
INSERT INTO `tb` VALUES ('012', '008', 1, '东区一街广场');
INSERT INTO `tb` VALUES ('013', '008', NULL, '东区一街大堂');
INSERT INTO `tb` VALUES ('014', '009', 0, '东区二街广场');
SET FOREIGN_KEY_CHECKS = 1;
上面的java类的的那些对象集合,就是用以下的sql进行查询出来的,查上级编号是003的无限下级记录。
select dist_no,
sponsorNo,
pin,
dist_name
from (select * from tb
order by sponsorNo, dist_no) tb_sorted,
(select @pv := '003') initialisation
where find_in_set(sponsorNo, @pv)
and length(@pv := concat(@pv, ',', dist_no))