2017-08-09 29 views
0

同級別的項目我有一個表:總額層次

id|name|parent 
-------------- 
1 |test|null 
2 |tt1 |1 
3 |tt2 |1 
4 |tt3 |1 
5 |tt4 |2 
6 |tt5 |3 
7 |tt6 |2 

,看起來像這樣的樹:

 test 
/ | \ 
    tt1 tt2 tt3 
/\  \ 
tt4 tt6  tt5 

的問題是如何找到在同一節點的數量級別作爲給定的節點。例如:對於tt2,答案是3,對於tt5答案也是3。但我沒有想法,該怎麼做?即使不談論最優化和正確的方式。

我已經創建了一個java實體,並將相應的映射映射到表中的同一列,並實現了一個返回到根的路徑的getter,以便我可以找到關卡。此外,我已經實現了一種方法,可以找到給定節點的兄弟姐妹數量。創建這些getters,因爲我認爲它會幫助我。

實體:

@Entity(name = "hierarchy") 

public class Hierarchy implements Serializable { 

    private Integer idNode; 
    private String name; 
    private Hierarchy parentNode; 
    private Set<Hierarchy> children; 

    public Hierarchy() { 
    } 

    public Hierarchy(Integer idNode, String name) { 
     this.idNode = idNode; 
     this.abbreviation = abbreviation; 
    } 

    @Id 
    @GeneratedValue 
    @Column(name = "id") 
    public Integer getIdNode() { 
     return idNode; 
    } 

    public void setIdNode(Integer idNode) { 
     this.idNode = idNode; 
    } 

    @Column(name = "name", length = 500) 
    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    @ManyToOne 
    @JoinColumn(name = "parent") 
    public Hierarchy getParentNode() { 
     return parentNode; 
    } 

    public void setParentNode(Hierarchy parentNode) { 
     this.parentNode = parentNode; 
    } 

    @OneToMany(mappedBy = "parentNode") 
    public Set<Hierarchy> getChildren() { 
     return children; 
    } 

    public void setChildren(Set<Hierarchy> children) { 
     this.children = children; 
    } 

    @Override 
    public String toString() { 
     return "Hierarchy [idNode=" + idNode + ", name=" + name + "]"; 
    } 

    @Transient 
    public int getSiblingsNum() { 
     if (this.getParentKeyword() == null) { 
      return -1; 
     } 
     return this.getParentNode().getChildren().size() - 1; 
    } 

    @Transient 
    public List<Hierarchy> getPath() { 
     Hierarchy name = this; 
     List<Hierarchy> path = new ArrayList<>(); 
     path.add(name); 
     while (name.getParentNode() != null) { 
      name = name.getParentNode(); 
      path.add(name); 
     } 
     return path; 
    } 

    @Override 
    public int hashCode() { 
     final int prime = 31; 
     int result = 1; 
     result = prime * result + ((idNode == null) ? 0 : idNode.hashCode()); 
     return result; 
    } 

    @Override 
    public boolean equals(Object obj) { 
     if (this == obj) 
      return true; 
     if (obj == null) 
      return false; 
     if (getClass() != obj.getClass()) 
      return false; 
     Hierarchy other = (Hierarchy) obj; 
     if (idNode == null) { 
      if (other.idNode != null) 
       return false; 
     } else if (!idNode.equals(other.idNode)) 
      return false; 
     return true; 
    } 
} 

回答

0

我會建議重新設計數據庫架構這樣的問題。您可以通過Bill Karwin章節天真樹來看書SQL反模式。

如果這不是一個選項,您必須導航到根目錄才能找到元素的級別,然後遞歸迭代直到找到的級別並計算所有元素。

事情是這樣的:

public int getSameLevelNum() { 
    int level = 0; 
    Hierarchy current = this; 
    while(current.getParentNode() != null){ 
     level++; 
     current = current.getParentNode(); 
    } 
    return recurse(current, level); 
} 

int recurse(Hierarchy node, int level){ 
    if(level == 0) return node.children.size(); 
    level--; 
    int r = 0; 
    for(Hierarchy child : node.children) 
      r+= recurse(child, level); 

    return r; 
} 
+0

與上升到根的解決方案是很清楚。我想也許可以採取其他方式。因爲樹相當大,每次計算都需要相當長的時間。無論如何感謝您的建議。 – Cap