根据某一节点,递归获取其所有子,父节点

1、数据表结构如:
在这里插入图片描述
2、需求:根据某一节点,递归获取其所有子,父节点,页面显示树状。如:
在这里插入图片描述3、接口:
Controller

@RequestMapping(value = "", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
  @PreAuthorize("hasAnyAuthority('QueryZoneManager')")
  @Log(name = "获取区域管理节点数据", type = "查询")
  @ApiOperation(value = "获取区域管理节点数据")
  @MultiTenant
  public Set<ZoneForData> queryZone(Principal principal) {
    JwtTokenUser user = (JwtTokenUser) ((OAuth2Authentication) principal).getUserAuthentication()
        .getPrincipal();
    if (StringUtils.isNotEmpty(user.getZoneId())) {
      return zoneService.findAllNodeById(user.getZoneId());
    } else {
      return zoneService.findAllNode();
    }
  }

Service

public Set<ZoneForData> findAllNodeById(String zoneId) {
    Set<ZoneForData> rootMenu = new HashSet<>();
    Optional<Zone> zones = zoneRepository.findById(zoneId);
    List<Zone> zoneList = zoneRepository.findAll();
    zoneList.forEach(r -> {
      ZoneForData zoneForData = ZoneForData.builder().id(r.getId()).nodename(r.getNodename())
          .pid(r.getPid()).level(r.getLevel()).createTime(r.getCreateTime())
          .createUser(r.getCreateUser())
          .build();
      rootMenu.add(zoneForData);
    });
    Set<ZoneForData> menuList = new HashSet<>();
    if(zones.isPresent()){
      ZoneForData zoneForData = ZoneForData.builder().id(zones.get().getId()).nodename(zones.get().getNodename())
          .pid(zones.get().getPid()).level(zones.get().getLevel()).createTime(zones.get().getCreateTime())
          .createUser(zones.get().getCreateUser())
          .build();
      menuList.add(zoneForData);
    }
    for (ZoneForData menu : menuList) {
      menu.setChildren(getChild(menu.getId(), rootMenu));
    }
    return menuList;
  }

private Set<ZoneForData> getChild(String id, Set<ZoneForData> managements) {
    // 子菜单
    Set<ZoneForData> childList = new HashSet<>();
    for (ZoneForData management : managements) {
      // 遍历所有节点,将父菜单id与传过来的id比较
      if (StringUtils.isNotBlank(management.getPid())) {
        if (management.getPid().equals(id)) {
          childList.add(management);
        }
      }
    }
    // 把子菜单的子菜单再循环一遍
    for (ZoneForData management : childList) {
      // 递归
      management.setChildren(getChild(management.getId(), managements));
    } // 递归退出条件
    if (childList.size() == 0) {
      return null;
    }
    return childList;
  }

返回的实体类

package com.atue.smarthome.manageplatform.domain.model;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.HashSet;
import java.util.Set;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class ZoneForData {
  private String id;
  private String nodename;
  private String pid;
  private Integer level;
  private String createUser;
  private Long createTime;
  private Set<ZoneForData> children =new HashSet<>();
}

5、根据节点id获取子、父所有节点。

@Query(value = "select id from `zone` where FIND_IN_SET(id,getZoneChildList(:zoneId));", nativeQuery = true)
    List<String> queryZoneChildListById(@Param("zoneId") String zoneId);

@Query(value = "select id from `zone` where FIND_IN_SET(id,getZoneParentList(:zoneId));", nativeQuery = true)
    List<String> queryZoneParentListById(@Param("zoneId") String zoneId);

存储过程

BEGIN DECLARE ptemp VARCHAR(10000); DECLARE ctemp VARCHAR(10000); SET ptemp = '#'; SET ctemp = rootId; WHILE ctemp IS NOT NULL DO SET ptemp = concat(ptemp, ',', ctemp); SELECT group_concat(id) INTO ctemp FROM zone WHERE FIND_IN_SET(pid, ctemp) > 0; END WHILE; RETURN ptemp; END


BEGIN DECLARE sTemp VARCHAR(10000); DECLARE sTempPar VARCHAR(10000); SET sTemp = ''; SET sTempPar =rootId; WHILE sTempPar is not null DO IF sTemp != '' THEN SET sTemp = concat(sTemp,',',sTempPar); ELSE SET sTemp = sTempPar; END IF; SET sTemp = concat(sTemp,',',sTempPar); SELECT group_concat(pid) INTO sTempPar FROM `zone` where pid<>id and FIND_IN_SET(id,sTempPar)>0; END WHILE; RETURN sTemp; END
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在MySQL中,有几种方法可以根据子节点获取它对应的所有父节点。 方法一:递归查询 可以使用递归查询来获取子节点对应的所有父节点。首先,我们需要为每个节点添加一个字段来保存它的父节点。然后,可以使用递归查询来获取所有父节点。 例如,假设我们有一个表格`nodes`,它具有以下结构: | id | name | parent_id | |----|----------|-----------| | 1 | 节点1 | null | | 2 | 节点2 | 1 | | 3 | 节点3 | 2 | | 4 | 节点4 | 3 | | 5 | 节点5 | 4 | 要获取节点5的所有父节点,可以使用以下递归查询: ``` WITH RECURSIVE parents AS ( SELECT parent_id, id, name FROM nodes WHERE id = 5 UNION ALL SELECT n.parent_id, n.id, n.name FROM nodes n JOIN parents p ON p.parent_id = n.id ) SELECT * FROM parents; ``` 这将返回子节点5的所有父节点,包括节点4、节点3、节点2和节点1。 方法二:使用连接查询 另一种方法是使用连接查询来获取子节点的所有父节点。这可以通过多次连接表格来实现。 以下是使用连接查询获取节点5的所有父节点的示例查询: ``` SELECT n1.* FROM nodes n1 JOIN nodes n2 ON n2.id = n1.parent_id JOIN nodes n3 ON n3.id = n2.parent_id JOIN nodes n4 ON n4.id = n3.parent_id WHERE n4.id = 5; ``` 这将返回节点5的所有父节点,包括节点4、节点3、节点2和节点1。 这些是在MySQL中根据子节点获取它对应的所有父节点的两种常见方法。具体使用哪种方法取决于你的数据结构和查询需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值