前言
最近项目中有个查询展示人员部门树(所有人员和部门一次性加载)的需求,谨以此篇博客手把手给大家分享下。
需求
如何把人员信息(大概一万条)插入到部门(大概三千多条)树中?并以人员部门树结构展示?
思路
一开始我觉得总共也就一万三千多条数据怎么递归怎么查数据库(想当然)都是不怎么耗时的,
结果实现后接口查询居然需要十秒多,显然是不符合要求的。后来,我把数据先从数据库查出来然后对其操作,耗时一秒左右。废话不多说,看实现过程。
实现
SysOfficeTreeVO
private Long id;
private Long parentId;
private string name;
private string type;
private List<SysOfficeTreeVO> children;
- 把所有部门信息查询出来形成一个officeList
List<SysOffice> sysOfficeList = sysOfficeMapper.selectByCondition(condition);
- 将部门list转成树VO的list,并设置类型为部门(type为0)用来区分VO是人员还是部门
List<SysOfficeTreeVO> sysOfficeTreeVOList = BeanMapperUtil.mapList(sysOfficeList, SysOfficeTreeVO.class);
sysOfficeTreeVOList.forEach(v -> v.setType(DataConstant.ZERO_STR));
- 所有人员信息查询出来形成一个userList
List<SysUser> allUser = sysUserMapper.select(sysUser);
- 把用户对象当作一个部门对象,用户的部门id当作VO中的parentId,同时设置类型为人员type为1
List<SysOfficeTreeVO> user2Offices = changeUser2Office(allUser);
- 将两个list(部门,人员)传入方法listToTree转成树形结构
private List<SysOfficeTreeVO> listToTree4User(List<SysOfficeTreeVO> list, List<SysOfficeTreeVO> userList) {
//根据treeUnique转成map
Map<Integer, SysOfficeTreeVO> map = list.stream().collect(Collectors.toMap(SysOfficeTreeVO::getId, v -> v));
//获取所有部门id
List<Integer> ids = list.stream().map(SysOfficeTreeVO::getId).collect(Collectors.toList());
List<SysOfficeTreeVO> tree = new ArrayList<>();
SysOfficeTreeVO parentTreeNode;
Integer pid;
//把部门list和用户list合并
list.addAll(userList);
// 循环用户和部门合并后list
for (SysOfficeTreeVO temp : list) {
//获取当前部门或者用户的父级id
pid = temp.getParentId();
// 如果部门ids不包含当前对象的父级id,说明当前对象是顶级部门
// 否则不是顶级部门也就是有父级部门,然后找到父级部门添加当前用户,
if (!ids.contains(pid)) {
tree.add(temp);
} else {
// 找到父级部门
parentTreeNode = map.get(pid);
if (parentTreeNode.getChildren() == null) {
parentTreeNode.setChildren(new ArrayList<>());
}
// 添加当前用户(此时list中的数据也就变了)
parentTreeNode.getChildren().add(temp);
}
}
return tree;
}
另一个例子
@RestController
@RequestMapping("/sys/test")
public class Test extends BaseController {
@GetMapping
public ResponseEntity list() {
List<SysOfficeTreeVO> list = Lists.newArrayList();
SysOfficeTreeVO sysOfficeTreeVO = new SysOfficeTreeVO();
sysOfficeTreeVO.setId(1);
sysOfficeTreeVO.setName("江西省");
sysOfficeTreeVO.setParentId(0);
list.add(sysOfficeTreeVO);
SysOfficeTreeVO sysOfficeTreeVO2 = new SysOfficeTreeVO();
sysOfficeTreeVO2.setId(3);
sysOfficeTreeVO2.setName("南昌市");
sysOfficeTreeVO2.setParentId(1);
list.add(sysOfficeTreeVO2);
SysOfficeTreeVO sysOfficeTreeVO6 = new SysOfficeTreeVO();
sysOfficeTreeVO6.setId(7);
sysOfficeTreeVO6.setName("肇庆市");
sysOfficeTreeVO6.setParentId(2);
list.add(sysOfficeTreeVO6);
SysOfficeTreeVO sysOfficeTreeVO3 = new SysOfficeTreeVO();
sysOfficeTreeVO3.setId(4);
sysOfficeTreeVO3.setName("上饶市");
sysOfficeTreeVO3.setParentId(1);
list.add(sysOfficeTreeVO3);
SysOfficeTreeVO sysOfficeTreeVO4 = new SysOfficeTreeVO();
sysOfficeTreeVO4.setId(5);
sysOfficeTreeVO4.setName("广州市");
sysOfficeTreeVO4.setParentId(2);
list.add(sysOfficeTreeVO4);
SysOfficeTreeVO sysOfficeTreeVO1 = new SysOfficeTreeVO();
sysOfficeTreeVO1.setId(2);
sysOfficeTreeVO1.setName("广东省");
sysOfficeTreeVO1.setParentId(0);
list.add(sysOfficeTreeVO1);
SysOfficeTreeVO sysOfficeTreeVO5 = new SysOfficeTreeVO();
sysOfficeTreeVO5.setId(6);
sysOfficeTreeVO5.setName("深圳市");
sysOfficeTreeVO5.setParentId(2);
list.add(sysOfficeTreeVO5);
List<SysOfficeTreeVO> listToTree = listToTree(list);
return successResult(listToTree);
}
private List<SysOfficeTreeVO> listToTree(List<SysOfficeTreeVO> list) {
Map<Integer, SysOfficeTreeVO> collect = list.stream().collect(Collectors.toMap(SysOfficeTreeVO::getId, v -> v));
List<SysOfficeTreeVO> tree = Lists.newArrayList();
Integer pid;
SysOfficeTreeVO parrent;
for (SysOfficeTreeVO sysOfficeTreeVO : list) {
if (sysOfficeTreeVO.getParentId() == 0) {
tree.add(sysOfficeTreeVO);
} else {
parrent = collect.get(sysOfficeTreeVO.getParentId());
if (parrent.getChildren() == null) {
parrent.setChildren(new ArrayList<>());
}
parrent.getChildren().add(sysOfficeTreeVO);
}
}
return tree;
}
}
写在最后
非常感谢大家的认真阅读,如有不足,还望各位看官多批评指正=_=
技术交流秋秋群:719023986
微x关注:干饭必备外卖神券,每天领大额卷
微x关注:正好想买,自助查桃宝京d卷