Java返回给前端一棵树形?那就用stream吧

    之前写项目,前端要求返回一棵树形,刚开始我还不知道,要递归遍历?这是肯定的,但是有些树形不知道它的深度。所以单纯的查询应该是不行。了解到可用Stream()方法,发现真的很好用,简直不要太爽。

先上实体类,这是一张地区表。我用的是MyBatis-Plus。
地区表获取:
链接:https://pan.baidu.com/s/1Ia8m9FjjYoyRw3qt574Wbw
提取码:zhl1

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;

import java.util.List;

@TableName("REGION")
public class RegionEntity {

   /**
    * 区域主键
    */
   @TableId("ID")
   private Integer id;

   /**
    * 区域名称
    */
   @TableField("NAME")
   private String name;

   /**
    * 父级id
    */
   @TableField("P_ID")
   private Integer pId;

   /**
    * 简称
    */
   @TableField("S_NAME")
   private String sName;

   /**
    * 等级
    */
   @TableField("LEVEL")
   private Integer level;

   /**
    * 区域编码
    */
   @TableField("CITY_CODE")
   private String cityCode;

   /**
    * 邮政编码
    */
   @TableField("EMAIL_CODE")
   private String emailCode;

   /**
    * 组合名称
    */
   @TableField("MER_NAME")
   private String merName;

   /**
    * 拼音
    */
   @TableField("PINYIN")
   private String pinYin;

   /**
    * 临时
    */
   @TableField(exist = false)
   List<RegionEntity> children;

   public Integer getId() {
       return id;
   }

   public void setId(Integer id) {
       this.id = id;
   }

   public String getName() {
       return name;
   }

   public void setName(String name) {
       this.name = name;
   }

   public Integer getpId() {
       return pId;
   }

   public void setpId(Integer pId) {
       this.pId = pId;
   }

   public String getsName() {
       return sName;
   }

   public void setsName(String sName) {
       this.sName = sName;
   }

   public Integer getLevel() {
       return level;
   }

   public void setLevel(Integer level) {
       this.level = level;
   }

   public String getCityCode() {
       return cityCode;
   }

   public void setCityCode(String cityCode) {
       this.cityCode = cityCode;
   }

   public String getEmailCode() {
       return emailCode;
   }

   public void setEmailCode(String emailCode) {
       this.emailCode = emailCode;
   }

   public String getMerName() {
       return merName;
   }

   public void setMerName(String merName) {
       this.merName = merName;
   }

   public String getPinYin() {
       return pinYin;
   }

   public void setPinYin(String pinYin) {
       this.pinYin = pinYin;
   }

   public List<RegionEntity> getChildren() {
       return children;
   }

   public void setChildren(List<RegionEntity> children) {
       this.children = children;
   }

   @Override
   public String toString() {
       return "RegionEntity{" +
               "id=" + id +
               ", name='" + name + '\'' +
               ", pId=" + pId +
               ", sName='" + sName + '\'' +
               ", level=" + level +
               ", cityCode='" + cityCode + '\'' +
               ", emailCode='" + emailCode + '\'' +
               ", merName='" + merName + '\'' +
               ", pinYin='" + pinYin + '\'' +
               ", children=" + children +
               '}';
   }
}

由于MyBatis-Plus有自带的BaseMapper,所以可用直接继承。
Mapper层:

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.recruit.talentadmin.entity.RegionEntity;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface RegionMapper extends BaseMapper<RegionEntity> {
}

Service层:

import com.recruit.talentadmin.entity.RegionEntity;
import java.util.List;
public interface RegionService {
   List<RegionEntity> listRegion();
   List<RegionEntity> listRegionTree();
}

Service实现类:(核心)

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.recruit.talentadmin.entity.RegionEntity;
import com.recruit.talentadmin.mapper.RegionMapper;
import com.recruit.talentadmin.service.RegionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

@Service
public class RegionServiceImpl implements RegionService {

    private RegionMapper regionMapper;

    @Autowired
    public void setRegionMapper(RegionMapper regionMapper) {
        this.regionMapper = regionMapper;
    }

    /**
     * 查询所有地区列表
     * @return
     */
    @Override
    public List<RegionEntity> listRegion() {
        QueryWrapper<RegionEntity> queryWrapper = new QueryWrapper<>(null);
        return regionMapper.selectList(queryWrapper);
    }
    
    @Override
    public List<RegionEntity> listRegionTree(){
        List<RegionEntity> regionEntityList = listRegion();
        return regionEntityList.stream()
                .filter(regionEntity -> regionEntity.getpId()==0)
                .peek(regionEntity -> regionEntity.setChildren(getChildren(regionEntity,regionEntityList)))
                .collect(Collectors.toList());
    }

    //递归查找所有地区的子区域
    private List<RegionEntity> getChildren(RegionEntity root, List<RegionEntity> all) {
        return all.stream()
                .filter(regionEntity -> regionEntity.getpId().equals(root.getId()))
                .peek(regionEntity -> regionEntity.setChildren(getChildren(regionEntity, all)))
                .collect(Collectors.toList());
    }
}

在实现类里边将listRegion()方法所得到的全部数据通过Stream()转化成流,通过filter过滤器先获取父节点是0的根节点,再掉用peek方法设置子节点。直接点是通过getChildren()方法获取的,与获取根节点原理相同。
Controller:

import com.recruit.talentadmin.common.Result;
import com.recruit.talentadmin.entity.RegionEntity;
import com.recruit.talentadmin.service.RegionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping("/system")
public class RegionController {

    private RegionService regionService;

    @Autowired
    public void setRegionService(RegionService regionService) {
        this.regionService = regionService;
    }

    @GetMapping("/listRegionTree")
    public Result<List<RegionEntity>> listRegionTree(){
        Result<List<RegionEntity>> result = new Result<>();
        List<RegionEntity> regionEntityList = regionService.listRegionTree();
        if(regionEntityList==null){
            result.setCode(500);
            result.setMsg("未查询到数据");
        }else {
            result.setData(regionEntityList);
            result.setMsg("查询成功");
            result.setCode(200);
        }
        return result;
    }
}

最后看看postmen测试效果:
在这里插入图片描述
效果达成,ok。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值