hibernate自身双向一对多 (链表结构对象)

摘自 [圣思园hibernate 017. 自身双向一对多关联关系深入解析]




数据库Schema: (Oracle)
create table test_categories(
ID number(15) not null,
name varchar2(15),
category_id number(15),
primary key (id)
);

alter table categories add index idx_category_id
(category_id), add constraint
fk_category_id foreign key (category_id) references
categories(id);



public class Category
{
	

	private Long id;
	
	private String name;
	
	private Category parentCategory;
	
	private Set<Category> childCategories;
	
	public Category()
	{
		// TODO Auto-generated constructor stub
	}
	
	public Category(String name, Category parentCategory,
			Set<Category> childCategories)
	{
		this.name = name;
		this.parentCategory = parentCategory;
		this.childCategories = childCategories;
	}
}


这里Category类实现了自身的一对多, 每一个Category有一个父表和若干的字表。
父表是它上一层的类, 比如CPU的父类表是电脑硬件,
而CPU的子类表可以是intel cpu和 amd cpu. ( 双向就是指向父类和向子类)
表的结构关联如下:






=========================具体实例====================

这里我们用一个计算机硬件的分类来演示这个自身双向一对多。
结构图:




Category.hbm.xml代码:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
  "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
  "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
          
  <hibernate-mapping package="com.lj.zhang.category">
  	<class name="Category" table="test_category" lazy="false">
  			<id name="id" column="id" type="long">
  				<generator class="sequence">
  					<param name="sequence">cate_seq</param>
  				</generator>
  			</id>
  			 <property name="name" column="name" type="string"/>
  			
  		<set name="childCategories" cascade="all" inverse="true">
  			<key column="category_id"></key>
  			<one-to-many class="com.lj.zhang.category.Category"/>
  		</set>
  		 
		<many-to-one name="parentCategory" class="com.lj.zhang.category.Category" column="category_id"></many-to-one>
  			
  	</class>
  
  
  </hibernate-mapping>
          
          

     

hibernate代码:

Session session = HibernateUtil.openSession();
		
		Transaction tx = null;

		tx = session.beginTransaction();
		
		
		Category c=new Category("computer",null,new HashSet<Category>());
		
		
		//这里没有通过cpu.setParent来指定父类, 而是直接在构造函数里将父类实例传递进去,下面都是这样。
		//setParent也可以实现同样效果。
		Category cpu=new Category("cpu",c,new HashSet<Category>());
		Category motherboard=new Category("motherboard",c,new HashSet<Category>());
	 	
		
		c.setChildCategories(ArraysHelper.asSet(cpu,motherboard));
		
		
		
 		Category intel_cpu=new Category("intel_cpu",cpu,new HashSet<Category>());
 		Category amd_cpu=new Category("amd_cpu",cpu,new HashSet<Category>());
 		cpu.setChildCategories(ArraysHelper.asSet(intel_cpu,amd_cpu));
 		
 		
 		Category asus=new Category("asus",motherboard,new HashSet<Category>());
 		Category giga=new Category("giga",motherboard,new HashSet<Category>());
 		motherboard.setChildCategories(ArraysHelper.asSet(asus,giga));
 		
 		
		
	 
		session.save(c);

		tx.commit();
		
		session.close();


注意这里是通过oracle的sequence来给id赋值:
<id name="id" column="id" type="long">
  				<generator class="sequence">
  					<param name="sequence">cate_seq</param>
  				</generator>
  			</id>


通过该程序可以看到, 只要把这些类的实例通过java的方式赋值,最后save它们的最高级的父类对象, 所有的对象都会被存储到数据库中, 并建立对应关系。
个人感觉Hibernate对于Java程序员的便利性在这个例子中得到充分体现。






------------------------------
数据库里显示最高级父类的cate id是没有任何数值的, 我们可以设置oracle给这种情况一个-1.
不过这里再次执行发现还是什么都没有。因为要在hibernate那里设置一下。

找到category.hbm.xml


猜你喜欢

转载自alleni123.iteye.com/blog/1976884
今日推荐