cvooc

树查询

oracle 树查询

1. 语句

select pid,id,name,level,connect_by_isleaf isleaf,order_code from t2 where level=1
start with pid = 0
connect by prior id = pid order siblings by order_code;

2. 规则解析

  1. start with, id= 是定义起始节点(种子),可以是 id 也可以是 pid,定义为 pid 查询该节点下所有的树结构,定义为 id(子节点)则查询指定的树。
  2. connect by prior, prior 的含义为先前,前一条记录。prior id=pid 也就是前一条记录的 id 等于当前记录的 pid(父 id)。id 还是 pid 的顺序决定树的是往上查询还是往下查询。
  3. level 字段为 oracle 的伪列,可以 level 通过字段查询指定的层级。从 1 开始。
  4. connect_by_isleaf 字段为 oracle 的 伪列,代表当前字段是否是叶子节点。1 代表叶子节点,0 代表枝干节点。

3. 查询结果解析(java 版)

private List<Map<String, Object>> getTree(List<Map<String, Object>> list) {
    Map<String, Map<String, Object>> levelMapTemp = new HashMap<String, Map<String, Object>>();
    List<Map<String, Object>> res = new ArrayList<Map<String, Object>>();
    // 获取root
    for (Map<String,Object> m : list) {
        Map<String, Object> menu = new HashMap<String, Object>();
        String level = String.valueOf(m.get("LEVEL"));
        String uplevel = String.valueOf(Integer.parseInt(level) - 1);
        menu.put("nodeId", m.get("NODE_ID"));
        menu.put("parentNodeId", m.get("PARENT_NODE_ID"));
        menu.put("nodeName", m.get("NODE_NAME"));
        menu.put("nodeType", m.get("NODE_TYPE"));
        if (!"1".equals(String.valueOf(m.get("LEAF")))) {// 子节点
            menu.put("children", new ArrayList<Map<String, Object>>());
        }
        levelMapTemp.put(level, menu);
        if ("1".equals(level)) {
            res.add(menu);
        } else {
            Map<String, Object> parent = levelMapTemp.get(uplevel);
            List<Map<String, Object>> chlst = (List<Map<String, Object>>) parent.get("children");
            chlst.add(menu);
        }
    }
    return res;
}