第一步:在数据库里建立两张关联的表,并添加若干数据

用户基本信息表user设计如下:

用户等级关系表user_task设计如下

第二步:编写对应的实体类

User类如下:

UserDto类如下所示(user表和userTask表的属性拼接),同时新增用于存放下级用户的Children集合:

package com.example.demo.DTO;

import lombok.Data;

import java.util.List;

@Data
public class UserDto {

    private int id;
    private String name;
    private int age;
    private String sex;
    private int superId;
    private String rankType;

    private List<UserDto> children;
  
}

 第三步:编写对应的mapper层代码

UserMapper.xml代码如下(两张表联合查询,将查到的记录映射成上面的UserDto,返回一个UserDto集合)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.Mapper.UserMapper">
    <select id = "getAllUser" resultType="com.example.demo.DTO.UserDto">
select u.id,u.name,u.age,u.sex,r.rank_type as rankType,r.super_id as superId
from user u left join user_rank r
on u.id = r.user_id
where 1=1
    </select>

</mapper>

userMapper接口层代码如下(注意:上图的namespace路径要和下图接口层的文件路径一致)

 第四步:service层实现(重点步骤)

首先需要拿到所有的用户数据,代码如下图:

 其次,筛选这些用户数据,找到最高级别的用户

然后,从这些最高级别的用户开始遍历,递归查找该用户的下级用户,将查找到的下级放入children集合内,再将children赋值给该用户。

最后,将带有children属性的用户放入结果集。

上面是整体思路,具体实现代码如下:

    /*
    以树形结构返回数据
     */
    @Override
    public List<UserDto> getUserTree()
    {
        List<UserDto> allUser = getAllUser();
        //最高级别用户集合
        List<UserDto> roots = new ArrayList<>();
        List<UserDto> res = new ArrayList<>();
        for(UserDto userDto :allUser)
        {
            //-1表示最高级别的用户
            if(userDto.getSuperId() == -1)
            {
                roots.add(userDto);
            }
        }
        //从最高级别用户开始遍历,递归找到该用户的下级用户,将带有下级的最高级用户放入返回结果中
        for(UserDto userDto :roots)
        {
            userDto=buildUserTree(allUser,userDto);
            res.add(userDto);
        }
        return  res;
    }
    /*
    功能:根据传入的用户,获取该用户的下属集合,将集合赋值给该用户的children属性,返回该用户
     */

    @Override
    public UserDto buildUserTree(List<UserDto> allUsers,UserDto userDto)
    {
        List<UserDto> children = new ArrayList<>();
        //遍历查到的所有用户
        for(UserDto userDto1:allUsers)
        {
            //-1代表根节点,无需重复比较
            if(userDto1.getSuperId()== -1)
                continue;
            //当前用户的上级编号和传入的用户编号相等,表示该用户是传入用户的下级用户
            if(userDto1.getSuperId() == userDto.getId())
            {
                //递归调用,再去寻找该用户的下级用户
                userDto1=buildUserTree(allUsers,userDto1);
                //当前用户是该用户的一个下级用户,放入children集合内
                children.add(userDto1);
            }
        }
        //给该用户的children属性赋值,并返回该用户
        userDto.setChildren(children);
        return userDto;
    }

最后:编写Controller,调用该方法,通过浏览器输入对应请求url即可看到以树形结构展示的数据

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐