数据格式如下:
"list": [
{
"id": "1278493774292496385",
"title": "前端开发",
"children": [
{
"id": "1278493774460268545",
"title": "vue"
},
{
"id": "1278493774544154625",
"title": "vue-adamin"
},
{
"id": "1278493774611263489",
"title": "elementUi"
}
]
},
{
"id": "1278493774669983746",
"title": "后端开发",
"children": [
{
"id": "1278493774686760961",
"title": "Java"
},
{
"id": "1278493774770647042",
"title": "c++"
}
]
},
{
"id": "1278493774854533122",
"title": "数据库开发",
"children": [
{
"id": "1278493774867116033",
"title": "mysql"
}
]
}
]
如何才能返回这样的数据格式呢?
首先我们分析一下这个数据的格式:
外层是一个json数据格式 , 一级分类
内层有一个children里面是嵌套的封装了很多对象
首先我们将外层和内层剖析出来建立两个相对应的实体类
OneSubject
package com.starcpdk.edu.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<>();
}
TwoSubject
package com.starcpdk.edu.eduservice.entity.subject;
import lombok.Data;
//二级分类
@Data
public class TwoSubject {
private String id;
private String title;
}
在OneSubject中包含有twoSubject的list对象集合
EduSubjectController
package com.starcpdk.edu.eduservice.controller;
import com.starcpdk.edu.commonutils.R;
import com.starcpdk.edu.eduservice.entity.subject.OneSubject;
import com.starcpdk.edu.eduservice.service.EduSubjectService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
/**
* <p>
* 课程科目 前端控制器
* </p>
*
* @author 姚云峰
* @since 2020-07-01
*/
@RestController
@RequestMapping("/eduservice/subject")
@CrossOrigin
public class EduSubjectController {
@Autowired
private EduSubjectService subjectService;
//添加课程分类
//获取到上传的文件 , 把文件内容读取出来
@PostMapping("addSubject")
public R addSubject(MultipartFile file){
//上传过来的excel文件
subjectService.saveSubject(file , subjectService);
return R.ok();
}
//课程分类的列表功能(树形结构)
@GetMapping("getAllSubject")
public R getAllSubject(){
//list集合中的泛型是一级分类 , 因为一级分类中含有多个二级分类
List<OneSubject> list = subjectService.getAllOneTwoSubject();
return R.ok().data("list" , list);
}
}
主要逻辑在service层中
package com.starcpdk.edu.eduservice.service.impl;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.starcpdk.edu.eduservice.entity.EduSubject;
import com.starcpdk.edu.eduservice.entity.excel.SubjectData;
import com.starcpdk.edu.eduservice.entity.subject.OneSubject;
import com.starcpdk.edu.eduservice.entity.subject.TwoSubject;
import com.starcpdk.edu.eduservice.listener.SubjectExcelListener;
import com.starcpdk.edu.eduservice.mapper.EduSubjectMapper;
import com.starcpdk.edu.eduservice.service.EduSubjectService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
/**
* <p>
* 课程科目 服务实现类
* </p>
*
* @author 姚云峰
* @since 2020-07-01
*/
@Service
public class EduSubjectServiceImpl extends ServiceImpl<EduSubjectMapper, EduSubject> implements EduSubjectService {
//添加课程分类
@Override
public void saveSubject(MultipartFile file , EduSubjectService subjectService) {
try {
//文件输入流
InputStream in = file.getInputStream();
//调用方法进行读取
EasyExcel.read(in , SubjectData.class , new SubjectExcelListener(subjectService)).sheet().doRead();
}catch (Exception e){
e.printStackTrace();
}
}
@Override
public List<OneSubject> getAllOneTwoSubject() {
//查询所有一级分类 parent_id=0
QueryWrapper<EduSubject> wrapperOne = new QueryWrapper<>();
wrapperOne.eq("parent_id" , "0");
wrapperOne.orderByAsc("sort", "id");
List<EduSubject> oneSubjectsList = baseMapper.selectList(wrapperOne);
//查询所有二级分类 parent_id!=0
QueryWrapper<EduSubject> wrapperTwo = new QueryWrapper<>();
wrapperTwo.ne("parent_id" , "0");
wrapperTwo.orderByAsc("sort", "id");
List<EduSubject> twoSubjectsList = baseMapper.selectList(wrapperTwo);
//创建list集合 , 用于存储最终的分装数据
List<OneSubject> finalSubjectList = new ArrayList<>();
//封装一级分类
//查询出来的所有的一级分类list集合遍历 , 得到每一个一级分类对象 , 获取每一个一级分类对象的值,
//封装到要求的list集合里面list<OneSubject>finalSubjectList
for (EduSubject eduOneSubject:oneSubjectsList){
//把eduOneSubject中的值获取到 , 放到oneSubject对象中
//多个OneSubject放到finalSubjectList中
OneSubject oneSubject = new OneSubject();
// oneSubject.setId(eduOneSubject.getId());
// oneSubject.setTitle(eduOneSubject.getTitle());
//与上边的代码等价 , 即将eduOneSubject对象中的值get出来然后set到oneSubject中
BeanUtils.copyProperties(eduOneSubject , oneSubject);//springboot封装的方法 , 将一个对象中的值取出来 , 赋值给领英对象
//分装二级分类
//在一级分类中遍历查询的所有的二级分类
//创建list集合 , 封装每个一级分类中的二级分类
List<TwoSubject> finalTwoSubjectList = new ArrayList<>();
for (EduSubject eduTwoSubject:twoSubjectsList) {
//判断当前外循环下的一级分类的id是否与当前内循环中对象的二级分类的parent_id是否相等 , 若相等则从eduTwoSubject中取出值放到twoSubject中 , 然后封装到finalTwoSubjectList中
if (eduOneSubject.getId().equals(eduTwoSubject.getParentId())){
//把eduTwoSubject对象中的值获取到 , 放到TwoSubject对象中
//多个twoSubject放到finalTwoSubjectList中
TwoSubject twoSubject = new TwoSubject();
BeanUtils.copyProperties(eduTwoSubject , twoSubject);
finalTwoSubjectList.add(twoSubject);
}
}
oneSubject.setChildren(finalTwoSubjectList);
finalSubjectList.add(oneSubject);
}
return finalSubjectList;
}
}
首先通过查询数据库将所有一级分类查询出来放到oneSubjectsList
集合中 , 然后查询所有二级分类 , 将查询到的数据放到twoSubjectsList
集合中。
将查询到的所有一级分类的数据所放的集合进行遍历 , 将查询一级分类的集合中的每一个对象中的title属性和parent_id属性赋值给根据返回数据类型构造的实体类的对象中 , 最后将这些对象再封装到此实体类对应的集合中。
在一级分类的循环中遍历二级分类 , 同一级分类一样 , 但是多一步判断 , 判断当前外循环即一级循环中的当前对象的id和二级分类中循环的对象的parent_id是否想等 , 想等则说明当前的二级分类对象是此一级分类的对应二级 , 因此将此对象的值赋值给根据数据构造的二级分类的实体类对象中 , 最后将当前一级分类下的二级分类的对象集合通过set方法将集合赋值给一级分类的对象集合中setChildren
。