(13)树状结构
树状图是一种数据结构 ,它由n个有限节点组成一个具有层次关系的集合。每个节点有0或者多个子节点,没有父节点的节点是根节点,每个非根节点只有一个父节点,除了根节点外每个子节点可以分为多个不相交的子树。树种每个节点是相同的数据类型。
在日常生活中,也有许多这样的例子,比如一个总公司,可以有多个子公司,一个子公司又会有多个部门,因为每个子节点只能有一个父节点,所以上下层之间的关系是onetomany 和manytoone的关系。
所以确定了类里面应有的属性 id set<Org>
(manytoone)Org(onetomany) 。之前学的group、user是两张表,这里是一张表
存储在数据库中的表如下,通过父节点来确定是谁的孩子。那么若想要求一个节点(如id=0)的孩子有哪些,则select * from Org where parent_id=0。若想要求一个节点(如id=1)的父节点,则select * from Org where id=1;
id Parent_id name
0 null 总公司
1 0 分公司1
2 0 分公司2
3 2 分公司2_1
@Entity
public class Org {
private int id;
private String name;
private Set<Org> children=new HashSet<Org>();
private Org parent;
@Id
@GeneratedValue
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@OneToMany(mappedBy="parent",cascade=CascadeType.ALL,fetch=FetchType.EAGER)//在表中,是在many中有one的id ,只有OneToMany中有mappedBy manytoone中没有
public Set<Org> getChildren() {
return children;
}
public void setChildren(Set<Org> children) {
this.children = children;
}
@ManyToOne(cascade=CascadeType.ALL)//因为是双向的,所以要设mappedBy
@JoinColumn(name="p_id")
public Org getParent() {
return parent;
}
public void setParent(Org parent) {
this.parent = parent;
}
}
Test
@org.junit.Test
public void Save(){
Org o=new Org();
o.setName("总公司");
Org o1=new Org();
o1.setName("分公司1");
Org o2=new Org();
o2.setName("分公司2");
Org o11=new Org();
o11.setName("分公司11");
Org o12=new Org();
o12.setName("分公司12");
//要设置好他们之间的关系
o.getChildren().add(o2);
o.getChildren().add(o1);
o1.getChildren().add(o11);
o1.getChildren().add(o12);
o1.setParent(o);
o2.setParent(o);
o11.setParent(o1);
o12.setParent(o1);
Session session=sf.getCurrentSession();
session.beginTransaction();
session.save(o);//因为org已经设置为级联操作,所以可以全部插入
/*
* 插入过程
* 插入o,因为o级联操作,会将它的孩子,全部插入。然后再插入o2
*/
session.getTransaction().commit();
}
@org.junit.Test
public void read() {
Save();
Session session=sf.getCurrentSession();
session.beginTransaction();
Org o=(Org) session.get(Org.class, 1);
print(o,0);
/*one to many fetch=EAGER
* 先输出总公司,然后输出分公司11、12 然后输出 2
*/
session.getTransaction().commit();
}
/*
总公司
----分公司1
--------分公司11
--------分公司12
----分公司2
*/
//树递归输出
private void print(Org o,int level ) {
String preStr="";//产出缩进
for(int i=0;i<level;i++){
preStr+="----";
}
System.out.println(preStr+o.getName());
for(Org child:o.getChildren()){
print(child,level+1);
}
}