需求
- 设计机构树,查询实验室所有机构
- 以某一节点为根节点,查询局部机构树
实现
- 思路:
- 自身嵌套查询
- 代码递归查询
- 数据库设计
CREATE TABLE `sys_dept` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
`name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '机构名',
`dept_logo` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '机构ID',
`parent_id` bigint NOT NULL COMMENT '上级机构',
`create_by` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '创建人',
`create_time` datetime NOT NULL COMMENT '创建时间',
`last_update_time` datetime NOT NULL COMMENT '更新人',
`last_update_by` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '更新时间',
`del_flag` tinyint NOT NULL DEFAULT '0' COMMENT '删除标志,-1删除,0正常',
PRIMARY KEY (`id`),
UNIQUE KEY `UK_DEPT_NAME` (`name`) USING BTREE COMMENT '机构名唯一性注解'
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
2.设计对象
@JsonIgnoreProperties(value = {"handler"})
public class SysDept implements Serializable {
private Long id;
private String name;
private String deptLogo;
//父机构节点,第一级节点设置为0
private Long parentId;
private String createBy;
@JsonFormat(pattern = "yyyy-MM-dd",timezone = "GMT+8")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date createTime;
@JsonFormat(pattern = "yyyy-MM-dd",timezone = "GMT+8")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date lastUpdateTime;
private String lastUpdateBy;
private Byte delFlag;
//三级权限嵌套查询使用
private List<SysUser> userList;
//构建机构树使用,子机构节点
private List<SysDept> deptList;
3.遍历获取子节点
private List<SysDept> getChildNodes(Long id, List<SysDept> rootList){
//新建字节点列表
List<SysDept> chileList = new ArrayList<>();
//根据父节点ID填充对应的字节点
for(SysDept sysDept : rootList){
if(sysDept.getParentId() != null){
if(sysDept.getParentId() == id){
chileList.add(sysDept);
}
}
}
if(chileList.size() == 0){
return null;
}
//便利子节点并且进行对应的填充
for(SysDept sysDept: chileList){
sysDept.setDeptList(getChildNodes(sysDept.getId(), rootList));
}
return chileList;
}
4.具体实现代码
@ApiOperation(value = "查询机构树",notes = "查询机构树")
@ApiImplicitParams({
@ApiImplicitParam(type = "query", name = "id", value = "机构树根目录ID,规定根目录的ID为1",required = true)
})
@PostMapping("/find/tree")
public HttpResult findDeptNodes(Long id){
try{
SysDept sysDept = sysDeptService.findById(id);
List<SysDept> rootList = sysDeptService.findRootTree();
List<SysDept> depts = getChildNodes(id, rootList);
sysDept.setDeptList(depts);
return HttpResult.ok(sysDept);
}catch (Exception e){
e.printStackTrace();
return HttpResult.error("查询失败");
}
}
-------改进一下–
- 根据父ID进行机构树查询
因为我们不知道顶级机构树的ID到底是哪一个,但是我们可以知道顶级机构的父机构ID,人为设置为-1就可以
@ApiOperation(value = "查询机构树",notes = "查询机构树")
@ApiImplicitParams({
@ApiImplicitParam(type = "query", name = "parentId", value = "规定根目录的父ID为-1,",required = true)
})
@PostMapping("/find/tree")
public HttpResult findDeptNodes(Long parentId){
try{
System.out.println("parentId:"+parentId);
List<SysDept> sysDepts = sysDeptService.findByParentId(parentId);
//SysDept sysDept = sysDeptService.findById(id);
List<SysDept> rootList = sysDeptService.findRootTree();
for(SysDept sysDept: sysDepts){
List<SysDept> depts = getChildNodes(sysDept.getParentId(), rootList);
sysDept.setDeptList(depts);
}
return HttpResult.ok(sysDepts);
}catch (Exception e){
e.printStackTrace();
return HttpResult.error("查询失败");
}
}