基于Hutool TreeUtil 实现后端返回数据树形结构
接下来模仿现实业务场景中,实现查询数据库得到数据,最后使用TreeUtil 处理数据,返回结果呈树形结构。
1:引入 Hutool 依赖
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.11</version>
</dependency>
2:数据库建表语句
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for department
-- ----------------------------
DROP TABLE IF EXISTS `department`;
CREATE TABLE `department` (
`id` int NOT NULL COMMENT '主键id 信息',
`name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '部门名称信息',
`pid` int NOT NULL COMMENT '父节点id 信息',
`status` int NULL DEFAULT NULL COMMENT '0:我呼死你 1:你被我打死了',
`desc` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '对部门信息的描述',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of department
-- ----------------------------
INSERT INTO `department` VALUES (1, '北京阿里云有限公司', 0, 0, '我是大公司');
INSERT INTO `department` VALUES (2, '郑州云智能有限公司', 0, 1, '我是郑州公司');
INSERT INTO `department` VALUES (3, '开发部', 1, 1, '我是大公司下的部门');
INSERT INTO `department` VALUES (4, '测试部', 1, 1, '我是大公司下的部门');
INSERT INTO `department` VALUES (5, '云计算', 2, 1, '我是郑州公司下的部门');
INSERT INTO `department` VALUES (6, '大数据', 2, 1, '我是郑州公司下的部门');
INSERT INTO `department` VALUES (7, '夏天', 3, 1, '我是开发部的成员');
INSERT INTO `department` VALUES (8, '齐天大圣', 3, 1, '我是测试部的成员');
INSERT INTO `department` VALUES (9, '高俊俊', 5, 1, '我是云计算下面的专业');
INSERT INTO `department` VALUES (10, '张三三', 6, 1, '我是大数据的人');
SET FOREIGN_KEY_CHECKS = 1;
3:Result 结果类 以及 ResultCode
public class Result implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
//状态码
private Integer code;
//响应消息
private String msg;
//响应数据
private Object data;
private Integer count;
public Integer getCount() {
return count;
}
public void setCount(Integer count) {
this.count = count;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public Result(ResultCode resultCode,Object data) {
this.code=resultCode.getCode();
this.msg=resultCode.getMsg();
this.data=data;
}
public Result(Integer code,String msg,Object data) {
this.code=code;
this.msg=msg;
this.data=data;
}
}
//ResultCode 类
public enum ResultCode {
SUCCESS(0,"成功"),
ERROR(500,"操作失败"),
private Integer code;
private String msg;
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
ResultCode(Integer code,String msg){
this.code=code;
this.msg=msg;
}
}
4:实体类
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Department {
private Integer id;
private String name;
private Integer pid; //父id
private Integer status;
private String desc;
/**
* 子目录列表
*/
private List<Department> treeNode;
}
5:Controller 层
@RestController
@RequestMapping("/department")
public class DepartmentController {
@Resource
private DepartmentService departmentService;
@PostMapping("treeDepartment")
public Result treeDepartment(){
List<Tree<String>> departmentAll = departmentService.findDepartmentAll();
return new Result(ResultCode.SUCCESS,departmentAll);
}
}
6:service 层
接口:
@Service
public interface DepartmentService {
List<Tree<String>> findDepartmentAll();
}
实现类:
@Service
public class DepartmentSericeImpl implements DepartmentService {
@Resource
private DepartmentMapper departmentMapper;
private static final String status = "status";
private static final String desc = "desc";
@Override
public List<Tree<String>> findDepartmentAll() {
List<Department> list = departmentMapper.findDepartmentAll();
List<Department> list2 = CollUtil.newArrayList();
//浅拷贝赋值
list2.addAll(list);
// rootId
String pid = "0";
//配置
TreeNodeConfig nodeConfig = new TreeNodeConfig();
// 自定义属性名 都要默认值的
//设置ID对应的名称
nodeConfig.setIdKey("id");
// 最大递归深度 3级目录
nodeConfig.setDeep(3);
// 入参
// tree: 最终要返回的数据
// node: lists数据
// 返回
// Tree<String>
// Tree: 转换的实体 为数据源里的对象类型
// String: ID类型
//转换器
List<Tree<String>> treeList = TreeUtil.build(list2, pid, nodeConfig,
(node, tree) -> {
//id
tree.setId(node.getId().toString());
//姓名
tree.setName(node.getName());
//获取父节点id
tree.setParentId(node.getPid().toString());
// 扩展的属性 ...
tree.putExtra(status, node.getStatus());
tree.putExtra(desc, node.getDesc());
});
return treeList;
}
}
7:mapper 层
@Mapper
public interface DepartmentMapper {
List<Department> findDepartmentAll();
}
mapper.xml文件:
<?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.demotest.mapper.DepartmentMapper">
<select id="findDepartmentAll" resultType="com.example.demotest.pojo.Department">
select * from department
</select>
</mapper>
8:查询结果如下
{
"code": 0,
"msg": "成功",
"data": [
{
"id": "1",
"name": "北京阿里云有限公司",
"parentId": "0",
"status": 0,
"desc": "我是大公司",
"children": [
{
"id": "3",
"name": "开发部",
"parentId": "1",
"status": 1,
"desc": "我是大公司下的部门",
"children": [
{
"id": "7",
"name": "夏天",
"parentId": "3",
"status": 1,
"desc": "我是开发部的成员",
"children": null
},
{
"id": "8",
"name": "齐天大圣",
"parentId": "3",
"status": 1,
"desc": "我是测试部的成员",
"children": null
}
]
},
{
"id": "4",
"name": "测试部",
"parentId": "1",
"status": 1,
"desc": "我是大公司下的部门"
}
]
},
{
"id": "2",
"name": "郑州云智能有限公司",
"parentId": "0",
"status": 1,
"desc": "我是郑州公司",
"children": [
{
"id": "5",
"name": "云计算",
"parentId": "2",
"status": 1,
"desc": "我是郑州公司下的部门",
"children": [
{
"id": "9",
"name": "高俊俊",
"parentId": "5",
"status": 1,
"desc": "我是云计算下面的专业",
"children": null
}
]
},
{
"id": "6",
"name": "大数据",
"parentId": "2",
"status": 1,
"desc": "我是郑州公司下的部门",
"children": [
{
"id": "10",
"name": "张三三",
"parentId": "6",
"status": 1,
"desc": "我是大数据的人",
"children": null
}
]
}
]
}
],
"count": null
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 一文读懂知识蒸馏
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下