1、实现效果

我们在开发中都会遇到树形控件,今天就来实现这个功能,我这里这树形结构比较简单,只有二级分类,这里只写出后端实现,前端你只需要把数据拿到赋值给vue的树形控件即可,前端实现方式太简单,这里不做讨论。
我们最终想要的数据结构为:

 "list": [
      {
        "id": "1178214681118568449",
        "title": "后端开发",
        "children": [
          {
            "id": "1178214681139539969",
            "title": "Java"
          },
          {
            "id": "1178585108407984130",
            "title": "Python"
          },
          {
            "id": "1454645056483913730",
            "title": "C++"
          },
          {
            "id": "1454645056731377666",
            "title": "C#"
          }
        ]
      },
      {
        "id": "1178214681181483010",
        "title": "前端开发",
        "children": [
          {
            "id": "1178214681210843137",
            "title": "JavaScript"
          },
          {
            "id": "1178585108454121473",
            "title": "HTML/CSS"
          }
        ]
      },
      {
        "id": "1178214681231814658",
        "title": "云计算",
        "children": [
          {
            "id": "1178214681252786178",
            "title": "Docker"
          },
          {
            "id": "1178214681294729217",
            "title": "Linux"
          }
        ]
      },
      {
        "id": "1178214681324089345",
        "title": "系统/运维",
        "children": [
          {
            "id": "1178214681353449473",
            "title": "Linux"
          },
          {
            "id": "1178214681382809602",
            "title": "Windows"
          }
        ]
      },
      {
        "id": "1178214681399586817",
        "title": "数据库",
        "children": [
          {
            "id": "1178214681428946945",
            "title": "MySQL"
          },
          {
            "id": "1178214681454112770",
            "title": "MongoDB"
          }
        ]
      },
      {
        "id": "1178214681483472898",
        "title": "大数据",
        "children": [
          {
            "id": "1178214681504444418",
            "title": "Hadoop"
          },
          {
            "id": "1178214681529610242",
            "title": "Spark"
          }
        ]
      },
      {
        "id": "1178214681554776066",
        "title": "人工智能",
        "children": [
          {
            "id": "1178214681584136193",
            "title": "Python"
          }
        ]
      },
      {
        "id": "1178214681613496321",
        "title": "编程语言",
        "children": [
          {
            "id": "1178214681626079234",
            "title": "Java"
          }
        ]
      }
    ]

我的前端实现效果为:
在这里插入图片描述

2、数据库中的表结构

在这里插入图片描述

3、后端接口实现

3.1 针对返回的数据创建对应的实体类

这里创建两个实体类 分别对应一级分类和二级分类

package com.atguigu.eduservice.entity.subject;

import lombok.Data;

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

/**
 * 一级分类
 */
@Data
public class OneSubject {

    private String id;

    private String title;

    //一个一级分类有多个二级分类
    private List<TwoSubject> children=new ArrayList<>();
}

package com.atguigu.eduservice.entity.subject;

import lombok.Data;

/**
 * 二级分类
 */
@Data
public class TwoSubject {

    private String id;

    private String title;
}

一个一级分类对应多个二级分类

数据库对应的实体类为:


import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import java.util.Date;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;

@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value="EduSubject对象", description="课程科目")
public class EduSubject implements Serializable {

    private static final long serialVersionUID = 1L;

    @ApiModelProperty(value = "课程类别ID")
    @TableId(value = "id", type = IdType.ID_WORKER_STR)
    private String id;

    @ApiModelProperty(value = "类别名称")
    private String title;

    @ApiModelProperty(value = "父ID")
    private String parentId;

    @ApiModelProperty(value = "排序字段")
    private Integer sort;

    @ApiModelProperty(value = "创建时间")
    @TableField(fill = FieldFill.INSERT)
    private Date gmtCreate;

    @ApiModelProperty(value = "更新时间")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Date gmtModified;


}

3.2 编写具体封装代码

controller:

//课程分类列表(树形结构)
    @GetMapping("getAllSubject")
    public R getAllSubject(){
        //list集合中的泛型是一级分类
        List<OneSubject> list=subjectService.getAllOneTwoSubject();
        return R.ok()
                .data("list",list);
    }

R是我的统一结果封装类

service


import com.atguigu.eduservice.entity.EduSubject;
import com.atguigu.eduservice.entity.subject.OneSubject;
import com.baomidou.mybatisplus.extension.service.IService;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;

public interface EduSubjectService extends IService<EduSubject> {

    /**
     * 课程分类列表树形结构
     * @return
     */
    List<OneSubject> getAllOneTwoSubject();
}

service实现类

//课程分类列表  树形结构
    @Override
    public List<OneSubject> getAllOneTwoSubject() {
        //1、查询出所有的一级分类 parentid=0
        QueryWrapper<EduSubject> wrapperOne=new QueryWrapper<>();
        wrapperOne.eq("parent_id","0");
        List<EduSubject> oneSubjectList = baseMapper.selectList(wrapperOne);

        //2、查询出所有的二级分类 parentid!=0
        QueryWrapper<EduSubject> wrapperTwo=new QueryWrapper<>();
        wrapperOne.ne("parent_id","0");
        List<EduSubject> twoSubjectList = baseMapper.selectList(wrapperTwo);

        //创建List集合,用于存储最终封装数据
        List<OneSubject> finalSubjectList=new ArrayList<>();

        //3、封装一级分类
        //把查询出来的所有一级分类list集合遍历,得到每个一级分类的对象,获取每个一级分类对象里面的值
        //封装到要求的list集合中List<OneSubject> finalSubjectList
        for (int i = 0; i < oneSubjectList.size(); i++) {//遍历oneSubjectList集合
            //得到oneSubjectList每个eduSubject对象
            EduSubject eduSubject = oneSubjectList.get(i);

            //把eduSubject里面的值获取出来,放到OneSubject对象里面
            //多个OneSubject方法finalSubjectList里面
            OneSubject oneSubject=new OneSubject();
//            oneSubject.setId(eduSubject.getId());
//            oneSubject.setTitle(eduSubject.getTitle());
            //把eduSubject中的值复制到oneSubject中 会自动找到对应的属性进行复制
            BeanUtils.copyProperties(eduSubject,oneSubject);    //简便复制属性的方法
            finalSubjectList.add(oneSubject);

            //在一级分类循环遍历查询所有的二级分类
            //创建list集合封装每个一级分类的二级分类
            List<TwoSubject> twoFinalSubjectList=new ArrayList<>();
            //遍历二级分类List集合
            for (int m = 0; m < twoSubjectList.size(); m++) {
                //获取每个二级分类
                EduSubject tSubject = twoSubjectList.get(m);
                //判断二级分类的Parentid和一级分类的id是否相等
                if(tSubject.getParentId().equals(eduSubject.getId())){
                    //把tSubject的值复制到twoSubject里面,放到twoFinalSubjectList里卖
                    TwoSubject twoSubject=new TwoSubject();
                    BeanUtils.copyProperties(tSubject,twoSubject);
                    twoFinalSubjectList.add(twoSubject);
                }
            }
            //把一级分类下面的所有二级分类放到一级分类里面
            oneSubject.setChildren(twoFinalSubjectList)
        }
        return finalSubjectList;
    }

这里的想法就是先查询出所有的一级分类和二级分类,然后建立一个最终返回结果的集合(泛型是一级分类类型),然后开始遍历一级分类,如果不重复的话,就把则个一级分类对象加入最终的结果集合,然后在第二重循环里面开始遍历二级分类集合,每次遍历的过程中判断该二级分类对象的parentid(父id)属性和第一重循环的一级分类对象的id属性的值是否相等,如果相等,则把该二级分类对象加入一个临时的二级分类集合对象中。
在第二从循环的外面将二级分类对象的临时集合设置为一级分类对象的children集合对象属性中
至此,树形结构的数据创建完毕

3.3 swagger测试

在这里插入图片描述
点击上面的try it out 我们观察响应数据就行
在这里插入图片描述

到这里后端接口就洗完了,在前端的树形控件你只需要建立一个对应的数组对象接收,然后根据树形控件的api赋值即可,前端实现简单,且实现方式五花八门,这里不做介绍了。

在这里插入图片描述

Logo

前往低代码交流专区

更多推荐