ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

三层目录建树

2021-08-06 09:30:55  阅读:212  来源: 互联网

标签:目录 元素 List private 建树 ApiModelProperty value 三层 id


关键思想:

  • 1

最终返回给前台的是一个实体类,该类应该有一个Children字段(实体类属性中具有,或者继承方法来获得,本例子用的是继承)用来接受它的子元素,子元素同样也是该类,也具有Children字段(层层套娃);

  • 2

遍历数据库所有元素,将一级元素(父id等于0)直接添加到树中,(其实就是放在该类中),作为基础;

  • 3

然后嵌套循环进行再次遍历数据库,进行判断,如果有A元素的父id等于另外一个B元素的id,就将A元素添加到B元素的Children字段中进行储存,也就是将A元素作为B元素的子级;遍历完成之后,每个元素具有的子元素都被安排的明明白白,层级关系建立完成

  • 4
    这样返回到前台就是这样的数据
    在这里插入图片描述
    建立完成

具体步骤及代码

  • 1:数据库建立
    数据库元素应该具有自身id,父id来区别层级
    在这里插入图片描述
  • 2:进行数据库元素的全部查询

@Override
public List<GoodsCategoryTree> selectTree(GoodsCategory goodsCategory) {
   System.out.println("进入selectTree方法。。。");
   List<GoodsCategory> list = this.list(Wrappers.lambdaQuery(goodsCategory));
   System.out.println("打印进入gettree的list"+list);
   return getTree(this.list(Wrappers.lambdaQuery(goodsCategory)));
}

/**
 * 构建树
 *
 * @param entitys
 * @return
 */
private List<GoodsCategoryTree> getTree(List<GoodsCategory> entitys) {
   List<GoodsCategoryTree> treeList = entitys.stream()
         //过滤(当前id不等于它的父类id)
         .filter(entity -> !entity.getId().equals(entity.getParentId()))
         //同级类目,根据Sort排序
         .sorted(Comparator.comparingInt(GoodsCategory::getSort))
         //复制bean
         .map(entity -> {
            GoodsCategoryTree node = new GoodsCategoryTree();
            //转换类型(其实无所谓换不换都一样,两个类基本属性一样)
            //转换后,流输出就变成了List<GoodsCategoryTree>
            BeanUtil.copyProperties(entity,node);
            return node;
         }).collect(Collectors.toList());
         //将返回的list集合放进树形工具类中,处理后返回
   return TreeUtil.build(treeList, CommonConstants.PARENT_ID);
}

①selectTree方法中只是将数据库的数据按照条件查询出来,(一般不限制条件,限制的话也不能限制parentId,限制了会导致树形结构一级没有内容,后面返回到前台的就是空的)并放入getTree方法中;
②getTree方法主要是将查询到的数据转换成流,并进行筛选、排序、转换类等操作,最后以List< GoodsCategoryTree >的形式放入TreeUtil.build()方法中;
③TreeUtil.build()方法是整个树形的核心;通过两层循环,将每个元素都互相做比较,如果是其子类就放进去到它的children字段中,然后将parentId等于0的元素放入需要返回到前台的类中,也就是List< GoodsCategoryTree >类中;返回就是分层的实体类;
代码如下:

/**
 * @author
 */
@UtilityClass
public class TreeUtil {
   /**
    * 两层循环实现建树
    *
    * @param treeNodes 传入的树节点列表
    * @return
    */
   //因为改类继承了TreeNode类,所以才会有该类的addChildren方法
   public <T extends TreeNode> List<T> build(List<T> treeNodes, Object root) {
      //T 类型为 GoodsCategoryTree  root = 0
      List<T> trees = new ArrayList<>();
      //遍历 list中每一个元素为treeNode
      for (T treeNode : treeNodes) {
         //先把父id等于0的,也就是第一级添加到树结构中
         if (root.equals(treeNode.getParentId())) {
            //如果元素父类id为0,就添加
            trees.add(treeNode);
//          trees.sort(Comparator.comparing(TreeNode::getSort));
         }
         //就再次遍历所有,包括已经添加到树中的
         for (T it : treeNodes) {
            //遍历所有,如果有元素的父id等于该元素的id,就成为其子类,不管几层,最后都会按层级排序
            if (it.getParentId().equals(treeNode.getId())) {
               treeNode.addChildren(it);
//             treeNode.getChildren().sort(Comparator.comparing(TreeNode::getSort));
            }

         }
      }
      return trees;
   }

其中泛型T是方法传进来的,这里也就是List< GoodsCategoryTree >类,看一下实体类:

/**
 * 商品类目
 *
 * @author JL
 * @date 2019-08-12 11:46:28
 */
@Data
@EqualsAndHashCode(callSuper = true)
public class GoodsCategoryTree extends TreeNode {

   /**
    * 所属租户
    */
   @ApiModelProperty(value = "所属租户")
   private String tenantId;
   /**
    * (1:开启;0:关闭)
    */
   @ApiModelProperty(value = "1:开启;0:关闭")
   private String enable;
   /**
    * 父分类编号
    */
   @ApiModelProperty(value = "父分类编号")
   private String parentId;
   /**
    * 名称
    */
   @ApiModelProperty(value = "名称")
   private String name;
   /**
    * 描述
    */
   @ApiModelProperty(value = "描述")
   private String description;
   /**
    * 图片
    */
   @ApiModelProperty(value = "图片")
   private String picUrl;
   /**
    * 排序
    */
   @ApiModelProperty(value = "排序")
   private Integer sort;
   /**
    * 创建时间
    */
   @ApiModelProperty(value = "创建时间")
   private LocalDateTime createTime;
   /**
    * 最后更新时间
    */
   @ApiModelProperty(value = "最后更新时间")
   private LocalDateTime updateTime;
   /**
    * 逻辑删除标记(0:显示;1:隐藏)
    */
   @ApiModelProperty(value = "逻辑删除标记")
   private String delFlag;
   /**
    * 跳转页面
    */
   @ApiModelProperty(value = "跳转页面")
   private String page;
}

并没有children字段,但是需要用到这个字段来进行子元素的存储,前文也提到,要么建字段,要么继承有这个字段的类,这里选择的继承类;

//因为改类继承了TreeNode类,所以才会有该类的addChildren方法
public <T extends TreeNode> List<T> build(List<T> treeNodes, Object root)

继承的这个类

package com.uk.mall.cloud.common.core.entity;

import lombok.Data;

import java.util.ArrayList;
import java.util.List;

/**
 * @author
 */
@Data
public class TreeNode {
//在本方法中需要用到的属性写上
   protected String id;
   protected String parentId;
   private Integer sort;
   protected List<TreeNode> children = new ArrayList<>();

   public void addChildren(TreeNode treeNode) {
      children.add(treeNode);
   }

   public List<TreeNode> getChildren() {
      if(children.size()<=0){
         return null;
      }
      return children;
   }
}

继承的类里面需要写上在这个方法中需要用到的属性,因为在该类中暂时类型还是泛型T,所以无法通过.get的方法来获取参数属性,继承类可以解决;

  • 3:分层完成,返回前端页面即可;
    需要多加分层只需要添加相应的元素,将父id指向已存在的id就行

标签:目录,元素,List,private,建树,ApiModelProperty,value,三层,id
来源: https://blog.csdn.net/Adda_Chen/article/details/117449442

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有