我有一张桌子:
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 Entity,其对应的映射到表中的同一列,并实现了一个getter,它返回root的路径,以便我可以找到该级别。此外,我已经实现了一个方法,可以找到给定节点的兄弟节点数量。创造了这些吸气剂,因为我认为它会对我有所帮助。
实体:
@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 :(得分:0)
我建议为这样的问题重新设计数据库模式。您可以查看Bill Karwin章节“天真树”中的SQL Antipatterns一书。
如果这不是一个选项,你必须导航到根目录才能找到元素的级别,然后递归迭代直到找到的级别并计算所有元素。
这样的事情:
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;
}