组织树列表查询,不使用递归一次循环搞定

Posted lvtao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了组织树列表查询,不使用递归一次循环搞定相关的知识,希望对你有一定的参考价值。

需求:不使用递归查询出一棵树。

service层业务代码

 1 @SuppressWarnings("unchecked")
 2     public JsonRet getOrganizationList(HttpServletRequest request, HttpServletResponse response) {
 3         LOG.d("getOrgnazationList");
 4         // 从Session得到用户信息
 5          HttpSession session = request.getSession();
 6         TuUser tuUser = (TuUser) session.getAttribute(Constant.USER_INFO);
 7         List<TuOrganization> organizationList = tuOrganizationMapper.getOrganizationList(tuUser.getBranchNo());
 8 
 9         Map<String, Object> item;
10         //获取根节点的集合
11         List<Map<String, Object>> root = new ArrayList<>();
12         Map<String, Map<String, Object>> tempMap = new HashMap<>();
13         //子节点集合
14         List<Map<String, Object>> children;
15         for(TuOrganization o : organizationList) {
16             children = new ArrayList<>();
17             item = new HashMap<>();
18             item.put("id", o.getId());
19             item.put("parentId", o.getParentId());
20             item.put("created", o.getCreateTime());
21             item.put("name", o.getName());
22             item.put("sort", o.getSort());
23             item.put("status", o.getStatus());
24             item.put("children", children);
25             //每次循环都将集合重新循环添加到父集合中
26             tempMap.put(o.getId(), item);
27             Map<String, Object> parent = tempMap.get(o.getParentId());
28             if(null != parent) {
29                 //父集合不为空时,获取下级集合
30                 ((List<Map<String, Object>>)parent.get("children")).add(item);
31             } else {
32                 //根集合
33                 root.add(item);
34             }
35         }
36 
37         Comparator<Map<String, Object>> comparator = new Comparator<Map<String, Object>>() {
38             @Override
39             public int compare(Map<String, Object> o1, Map<String, Object> o2) {
40                 //根据sort字段进行排序
41                 Integer i1 = ((Integer)o1.get("sort"));
42                 Integer i2 = ((Integer)o2.get("sort"));
43                 if(i1 > i2) {
44                     return 1;
45                 } else if(i1 < i2) {
46                     return -1;
47                 }
48                 //若sort字段相同的话,根据创建时间来进行排序
49                 Date d1 = ((Date)o1.get("created"));
50                 Date d2 = ((Date)o2.get("created"));
51                 if(null == d1 || null == d2) return 0;
52                 return d1.compareTo(d2);
53             }
54         };
55 
56         Collections.sort(root, comparator);
57         for (Map.Entry<String, Map<String, Object>> entry : tempMap.entrySet()) {
58             Collections.sort(((List<Map<String, Object>>)entry.getValue().get("children")), comparator);
59         }
60 
61         return jsonResponse(root, Constants.CODE_SUCCESS, "成功");
62     }

 

在循环内封装tempMap,然后直接就可以调用,是因为在SQL中对path做了排序,越往根级的组织越先被遍历到,或者可以直接遍历两次,第一次用来封装temMap,这样SQL语句中就不需要path排序,getOrganizationList SQL语句如下

  <select id="getOrganizationList" parameterType="java.lang.String" resultMap="BaseResultMap">
   select
    <include refid="Base_Column_List" />
    from tu_organization where branch_no = #{branchNo,jdbcType=VARCHAR} order by path
  </select>

path:组织路径;例:1-2-3 代表当前组织parent是组织2,组织2的parent是组织1,每个branch_no下的path都从1开始,且格式必须为‘1-2-3 ...’

技术分享图片

 This idea is from my leader lixiang

以上是关于组织树列表查询,不使用递归一次循环搞定的主要内容,如果未能解决你的问题,请参考以下文章

不一样的ZTree,权限树.js插件

java代码递归部门结构树

react 使用antd的TreeSelect树选择组件实现多个树选择循环

实现一个比较低效但可以成功跑通的父子id表查询数据

跟踪递归方法的进度

组织机构树数据库表设计