欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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;
        }

    }

好了看 结果
java 构造一个n层树数据结构(只查询一次数据库)这样就ok了。
这个方法比较容易理解,也是有需要改进的地方的,但是工作上用之类的是没什么问题的。

本文地址:https://blog.csdn.net/levi_fff/article/details/107661920

相关标签: java spring