树状结构的设计(把一棵树存入数据库的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
从面向对象的设计角度出发,在树的节点类中不宜放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
相关文章推荐
- Hibernate学习笔记_关系映射_树状结构练习
- 数据库的设计及hibernate实体映射 【转】
- hibernate之树状映射结构
- 数据库的设计及hibernate实体映射
- 【hibernate框架】练习-树状结构设计(非常重要)
- Hibernate 另一个作业:Org树状结构设计
- hibernate树状结构映射
- Hibernate之树状结构设计
- hibernate注解形式的树状结构设计
- Hibernate学习实例:关联表的树状结构设计
- hibernate映射应用 - 树状结构
- hibernate学习(设计一对多 关系 映射)
- 使用Hibernate 创建数据表时,如何使数据库中的字段的长度和Hibernate映射的长度相等呢?
- 树形结构的数据库表Schema设计
- 树形结构的数据库表Schema设计
- 使用MiddleGen 产生hibernate的数据库表映射文件
- 用hibernate跨数据平台将数据存入数据库中
- 树形结构的数据库表Schema设计
- 常见数据库设计(4)——树形结构数据
- hibernate课程 初探一对多映射2-4 Mysql创建数据库表