hibernate实现Tree

Tree是一种比较常见的数据展示类型,本文简单探讨一下hibernate实现创建Tree的过程。

首先简介一下Tree,每一个节点需要有一个对父节点id的引用,即Tree实体类中需要有对父节点的引用,使用Many2One,当然,关联是双向的,同时,还要有对子节点的引用,使用One2Many,因为关联是双向的,所以会使用到mappedBy

1.本例使用树实体类使用Org,除声明id和name属性外,还需要引用父节点Org parent,并在getParent上使用ManyToOne

同时需要引用子节点的集合Set<Org> children,并在getChildren上使用@OneToMany(mappedBy="parent")

Org

package com.baosight.model;

import java.util.*;

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 String id;
	private String name;
	private Set<Org> children = new HashSet<Org>();
	private Org parent;
	@Id
	@GeneratedValue//auto
	public String getId() {
		return id;
	}
	public void setId(String 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> getChildren() {
		return children;
	}
	public void setChildren(Set<Org> children) {
		this.children = children;
	}
	@ManyToOne
	@JoinColumn(name="parent_id")
	public Org getParent() {
		return parent;
	}
	public void setParent(Org parent) {
		this.parent = parent;
	}
}

hibernate的配置文件hibernate.cfg.xml

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

    <session-factory>

        <!-- Database connection settings -->
        <property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
        <property name="connection.url">jdbc:oracle:thin:@127.0.0.1:1521:orcl</property>
        <property name="connection.username">scott</property>
        <property name="connection.password">tiger</property>

        <!-- JDBC connection pool (use the built-in) -->
        <!-- <property name="connection.pool_size">1</property> -->

        <!-- SQL dialect -->
        <property name="dialect">org.hibernate.dialect.Oracle9iDialect</property>

        <!-- Enable Hibernate's automatic session context management -->
        <property name="current_session_context_class">thread</property>

        <!-- Disable the second-level cache  -->
        <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>

        <!-- Echo all executed SQL to stdout -->
        <property name="show_sql">true</property>
<!--         <property name="format_sql">true</property> -->

        <!-- Drop and re-create the database schema on startup -->
     <!--    <property name="hbm2ddl.auto">update</property> -->

		<mapping class="com.baosight.model.Org"/>
    </session-factory>

</hibernate-configuration>


JUnit测试类

package com.baosight.model;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.cfg.Configuration;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

public class OrMappingTest {
	private static SessionFactory sf = null;
	@BeforeClass
	public static void beforeClass(){
		new SchemaExport(new AnnotationConfiguration().configure()).create(false, true);
		// 读取配置文件
		Configuration cfg = new AnnotationConfiguration();
		// 得到session工厂
		sf = cfg.configure().buildSessionFactory();
	}
	
	@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("分公司3");
		Org o11 = new Org();
		o11.setName("分公司1部门1");
		Org o12 = new Org();
		o12.setName("分公司1部门2");
		Org o21 = new Org();
		o21.setName("分公司2部门1");
		o.getChildren().add(o1);
		o.getChildren().add(o2);
		o.getChildren().add(o3);
		o1.getChildren().add(o11);
		o1.getChildren().add(o12);
		o2.getChildren().add(o21);
		o1.setParent(o);
		o2.setParent(o);
		o3.setParent(o);
		o11.setParent(o1);
		o12.setParent(o1);
		o21.setParent(o2);
		Session session = sf.getCurrentSession();
		session.beginTransaction();
		session.save(o);
		session.getTransaction().commit();
	}
	@Test
	public void testLoad() {
		testSave();
		Session s = sf.getCurrentSession();
		s.beginTransaction();
		Org o = (Org) s.load(Org.class, "1");
		//输出Tree
		print(o,0);
		s.getTransaction().commit();
	}
	private void print(Org o, int level) {
		// TODO Auto-generated method stub
		String preStr = "";
		for(int i=0;i<level;i++){
			preStr +="----";
		}
		System.out.println(preStr+o.getName());
		for(Org org:o.getChildren()){
			print(org,level+1);
		}
	}

	/*@Test
	public void testSchemaExport() {
	}*/
	@AfterClass
	public static void afterClass(){
		// 关闭session工厂
		sf.close();
	}
}
2.使用testSave进行测试,要想在保存父节点的同时保存子节点,需要设置@OneToMany的cascade=CascadeType.ALL,并且,设置父节点和子节点之间的双向引用关系

测试结果

hibernate实现Tree_第1张图片hibernate实现Tree_第2张图片

3.使用testLoad打印Tree

3.1不使用fetch时的结果

hibernate实现Tree_第3张图片

3.2在@OneToMany使用fetch=FetchType.EAGER时的结果为

以上即为hibernate对于Tree的简单实现,在具体使用到Tree时,还需要做相关的调整,需要仔细体会。

你可能感兴趣的:(Hibernate,tree,one2many,many2one)