例如公司的组织机构:一个公司可以有多个子公司,一个子公司子有多个部门。
其实就是一张表,
例子程序:
Organization类:
package com.oracle.hibernate; 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 Organization { private int id; private String name; //父机构 private Organization parent; //一个父机构可有多个子机构 private Set<Organization> children = new HashSet<Organization>(); @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; } /** * 对于父机构:多对一 * pid是本机构的外键,指向父机构的标识,其实就是指向父机构的id */ @ManyToOne @JoinColumn(name="pid") public Organization getParent() { return parent; } public void setParent(Organization parent) { this.parent = parent; } /** * 对于子机构:一对多 *设mappedBy, *fetch=EAGER可以加载父机构时全部加载子机构。机构树小 时可以用,树大时可用ajax异步 * */ @OneToMany(mappedBy="parent",cascade=CascadeType.ALL,fetch=FetchType.EAGER) public Set<Organization> getChildren() { return children; } public void setChildren(Set<Organization> children) { this.children = children; } }
测试类:
package com.oracle.hibernate; import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.AnnotationConfiguration; import org.hibernate.tool.hbm2ddl.SchemaExport; import org.junit.AfterClass; import org.junit.BeforeClass; public class Test { private static SessionFactory sf = null; @BeforeClass public static void beforeClass() { try { // 生成表 new SchemaExport(new AnnotationConfiguration().configure()).create( false, true); sf = new AnnotationConfiguration().configure() .buildSessionFactory(); } catch (HibernateException e) { // TODO Auto-generated catch block e.printStackTrace(); } } @org.junit.Test public void testSchemaExport() { new SchemaExport(new AnnotationConfiguration().configure()).create( false, true); } @AfterClass public static void afterClass() { sf.close(); } @org.junit.Test public void testSave() { Session s = sf.getCurrentSession(); s.beginTransaction(); Organization org = new Organization(); org.setName("总公司"); Organization org2 = new Organization(); Organization org3 = new Organization(); Organization org4 = new Organization(); Organization org5 = new Organization(); org2.setName("分公司1"); org3.setName("分公司2"); org4.setName("分公司1_部门1"); org5.setName("分公司1_部门2"); org2.setParent(org); org3.setParent(org); org4.setParent(org2); org5.setParent(org2); org.getChildren().add(org2); org.getChildren().add(org3); org.getChildren().add(org4); org.getChildren().add(org5); s.save(org); s.getTransaction().commit(); } @org.junit.Test public void testLoad() { testSave();// 生成数据 Session s = sf.getCurrentSession(); s.beginTransaction(); Organization org = (Organization) s.load(Organization.class, 1); print(org, 0); s.getTransaction().commit(); } // 递归显示目录结构 private void print(Organization org, int level) {// level标识级别 String preStr = ""; for (int i = 0; i < level; i++) { preStr += "---"; // 级别往下一级,缩进 } System.out.println(preStr + org.getName()); for (Organization o : org.getChildren()) { print(o, level + 1); } } }
生成的表:
打印树状结构:
总公司
---分公司1
------分公司1_部门2
------分公司1_部门1
---分公司2