摘自 [b][圣思园hibernate 017. 自身双向一对多关联关系深入解析][/b]
[img]http://dl2.iteye.com/upload/attachment/0091/2882/e4ab2dd6-5a5a-313e-9b19-21253e2c3503.jpg[/img]
数据库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);
这里Category类实现了自身的一对多, 每一个Category有一个父表和若干的字表。
父表是它上一层的类, 比如CPU的父类表是电脑硬件,
而CPU的子类表可以是intel cpu和 amd cpu. ([b][color=darkred]双向[/color][/b]就是指向父类和向子类)
表的结构关联如下:
[img]http://dl2.iteye.com/upload/attachment/0091/2892/14166a1a-7794-3220-9229-9900bb2adcce.jpg[/img]
=========================具体实例====================
这里我们用一个计算机硬件的分类来演示这个自身双向一对多。
结构图:
[img]http://dl2.iteye.com/upload/attachment/0091/3024/94b7011d-8c9e-3dce-8945-8881957b57e6.jpg[/img]
Category.hbm.xml代码:
hibernate代码:
注意这里是通过oracle的sequence来给id赋值:
通过该程序可以看到, 只要把这些类的实例通过java的方式赋值,最后save它们的最高级的父类对象, 所有的对象都会被存储到数据库中, 并建立对应关系。
个人感觉Hibernate对于Java程序员的便利性在这个例子中得到充分体现。
[img]http://dl2.iteye.com/upload/attachment/0091/3026/41218aac-2a11-3ad9-b217-40e732c78b4c.jpg[/img]
------------------------------
[color=white]数据库里显示最高级父类的cate id是没有任何数值的, 我们可以设置oracle给这种情况一个-1.
不过这里再次执行发现还是什么都没有。因为要在hibernate那里设置一下。
找到category.hbm.xml[/color]
[img]http://dl2.iteye.com/upload/attachment/0091/2882/e4ab2dd6-5a5a-313e-9b19-21253e2c3503.jpg[/img]
数据库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. ([b][color=darkred]双向[/color][/b]就是指向父类和向子类)
表的结构关联如下:
[img]http://dl2.iteye.com/upload/attachment/0091/2892/14166a1a-7794-3220-9229-9900bb2adcce.jpg[/img]
=========================具体实例====================
这里我们用一个计算机硬件的分类来演示这个自身双向一对多。
结构图:
[img]http://dl2.iteye.com/upload/attachment/0091/3024/94b7011d-8c9e-3dce-8945-8881957b57e6.jpg[/img]
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程序员的便利性在这个例子中得到充分体现。
[img]http://dl2.iteye.com/upload/attachment/0091/3026/41218aac-2a11-3ad9-b217-40e732c78b4c.jpg[/img]
------------------------------
[color=white]数据库里显示最高级父类的cate id是没有任何数值的, 我们可以设置oracle给这种情况一个-1.
不过这里再次执行发现还是什么都没有。因为要在hibernate那里设置一下。
找到category.hbm.xml[/color]