您的位置:首页 > 数据库

树状结构的设计(把一棵树存入数据库的hibernate映射,及数据库表的设计)

2010-12-22 21:21 519 查看
数据库模型(id-pid):一个父亲有多个孩子,而一个孩子只有一个父亲,这样的结构就是一颗树。在数据库表中,设计的是id和pid(parent_id)。通过id和pid就存放一颗树了。
从面向对象的设计角度出发,在树的节点类中不宜放pid,一个节点有1个或者0个父亲,而有0个或者孩子。因此设计如下:这是一个组织机构,每个机构有父机构和子机构。
package com.xie.hibernate.modal;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
@Entity
public class Org {
private int id;
private String name;
private Set<Org> childrenOrgs=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)
public Set<Org> getChildrenOrgs() {
return childrenOrgs;
}
public void setChildrenOrgs(Set<Org> childrenOrgs) {
this.childrenOrgs = childrenOrgs;
}
@ManyToOne
@JoinColumn(name="p_id")
public Org getParent() {
return parent;
}
public void setParent(Org parent) {
this.parent = parent;
}
}
下面是junit的测试方法:
//生成数据库表,同时插入数据:
@Test
public void testSave(){
Org o=new Org();
o.setName("总公司");
Org o1=new Org();
o1.setName("分公司1");
Org o2=new Org();
o2.setName("分公司2");
Org o3=new Org();
o3.setName("分公司1的分公司1");
Org o4=new Org();
o4.setName("分公司1的分公司2");
Org o5=new Org();
o5.setName("分公司2的分公司1");
Org o6=new Org();
o6.setName("分公司1的分公司1分公司1");

o1.setParent(o);
o2.setParent(o);
o3.setParent(o1);
o4.setParent(o1);
o5.setParent(o2);
o6.setParent(o3);
o.getChildrenOrgs().add(o1);
o.getChildrenOrgs().add(o2);
o1.getChildrenOrgs().add(o3);
o1.getChildrenOrgs().add(o4);
o2.getChildrenOrgs().add(o5);
o3.getChildrenOrgs().add(o6);
try {
Session session=sf.getCurrentSession();
session.beginTransaction();
//注解中加了cascade={CascadeType.ALL},只存跟节点就把整颗树
//存到了数据库。
session.save(o);
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
}

}
//load一棵树到内存,由于有fetch=FetchType.EAGER,Org(Org) //session.load(Org.class, 1);将树中的所以节点load到了内存,同时维护着
//父子节点的关系。
@Test
public void testLoad(){
testSave();
try {
Session session=sf.getCurrentSession();
session.beginTransaction();
Org o=(Org) session.load(Org.class, 1);
Print(o,0);
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
}
}
/*
* 递归打印出一颗树。
*/
private void Print(Org o,int level) {
String preLevel="";
for (int i = 0; i < level; i++) {
preLevel+="----";
}
System.out.println(preLevel+o.getName());
for (Org org:o.getChildrenOrgs()) {
Print(org,level+1);
}
}
}
输出结果:
总公司
----分公司1
--------分公司1的分公司1
------------分公司1的分公司1分公司1
--------分公司1的分公司2
----分公司2
--------分公司2的分公司1
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: