java 构造一个n层树数据结构(只查询一次数据库)
程序员文章站
2022-05-19 11:28:54
刚学java不久正在努力的小白。废话不多说 直接上代码。数据库对应实体类@Data//自动生成getset方法 是lombok插件的功能public class Subject implements Serializable { private static final long serialVersionUID = 1L; @ApiModelProperty(value = "课程类别ID") @TableId(value = "id", type = IdType.I...
刚学java不久正在努力的小白。
废话不多说 直接上代码。
数据库对应实体类
@Data//自动生成getset方法 是lombok插件的功能
public class Subject 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;
}
树的封装类 主要是要有id pid这两个属性 和 children这个子级数组
其他的属性看个人而定 都随意的,我这里就是除了加了一个children数组 其他的属性和实体类一模一样
@Data
public class TreeSubject {
private String id;
private String title;
private String parentId;
private Integer sort;
private Date gmtCreate;
private Date gmtModified;
private List children = new ArrayList();
}
service方法
方法一:
查询数据库,获取所有一级分类和所有n级分类数据。循环添加每个一级分类并在循环体中调用递归方法findChildren(方法二)来循环递归出所有子级分类。
//---------------递归设置树形结构操作--------
public List<TreeSubject> listSubjects() {
//查询获取所有一级分类,parent_id为0就是一级分类(根分类)
QueryWrapper<Subject> queryParentSubject = new QueryWrapper<>();
queryParentSubject.eq("parent_id", 0);
List<Subject> subjectsParent = subjectMapper.selectList(queryParentSubject);
//查询获取所有子分类 parent_id不为0
QueryWrapper<Subject> queryChildrenSubject = new QueryWrapper<>();
queryChildrenSubject.ne("parent_id", 0);
List<Subject> sChildren = subjectMapper.selectList(queryChildrenSubject);
//----------------------------以上操作只查询数据库一次,获取所有数据,一级分类和n级分类
//----------------------------最好别递归操作多次查询数据库 把查询数据库的操作抽取出来
//创建返回树封装类的数组 最终结果的数组
//泛型之所以是TreeSubject,因为Subject类里没有children子类数组
//所以要返回TreeSubject,TreeSubject有一个children这个子类数组,不然也没必要创建个这么个类了
List<TreeSubject> listTree = new ArrayList<>();
//foreach循环
for (Subject sParent : subjectsParent) {
//创建树封装类
TreeSubject subjectTreeSubject = new TreeSubject();
//把当前每个一级分类属性赋给树封装类
//BeanUtils是spring的一个工具类 copyProperties可以把相同属性赋给另个类的相同属性
//参数1是赋值类 参数2是被赋值的类
//参数1没有children 所以把出了children之外的所有属性都赋给参数2
BeanUtils.copyProperties(sParent, subjectTreeSubject);
//调用查询当前父分类的子分类,如果有,那就set到children数组里
//第一个参数是当前父分类,第二个参数是上面数据库查询到的所有子分类数据
subjectTreeSubject.setChildren(findChildren(subjectTreeSubject,sChildren));
//把当前一级类添加进list
listTree.add(subjectTreeSubject);
}
//返回list 也就是树形结构的数据
return listTree;
}
方法二
递归查询当前父类下面的所有子分类
/**
* subjectTreeSubject 是当前分类
* sChildren 是查询到的所有子分类
*/
//递归查询是否有子元素的方法
public List<TreeSubject> findChildren(TreeSubject subjectTreeSubject,List<Subject> sChildren) {
//如果传入的值为空 返回null
//空的就是 没有一个一级分类
if (subjectTreeSubject == null) {
return null;
}
//判断是否有子分类 如果有 继续操作 没有返回null
if (sChildren.size() > 0) {
//创建返回子分类的数组
ArrayList<TreeSubject> treeChildrenList = new ArrayList<>();
//遍历每个二级类并添加到treeChildrenList数组
for (Subject sC : sChildren) {
//每个子分类的pid和父分类的id做比较 如果相等 那么就证明有子分类
if (sC.getParentId().equals(subjectTreeSubject.getId())) {
//创建树封装类
TreeSubject treeSubject = new TreeSubject();
//用spring的工具类把当前子分类符直给树封装类
BeanUtils.copyProperties(sC, treeSubject);
//继续递归,直到没有子级元素为止
//把当前子类传进去,因为这个不是固定的,可能当前子分类也是其他子分类的父类
treeSubject.setChildren(findChildren(treeSubject,sChildren));
//把当前子分类添加到返回数组中
treeChildrenList.add(treeSubject);
}
}
//把子分类数组返回
return treeChildrenList;
} else {
return null;
}
}
好了看 结果
这样就ok了。
这个方法比较容易理解,也是有需要改进的地方的,但是工作上用之类的是没什么问题的。
本文地址:https://blog.csdn.net/levi_fff/article/details/107661920
上一篇: 吸粉、品宣、转化在微信营销中的注意事项