Hibernate的映射关联关系和我们现实世界里事物的关联关系一样.比如在UML语言中,以客户Customer和订单Order的关系为例.一个客户可以发送多个订单,而一个订单只能属于一个客户,这是一对多的关联,因此可以成为单向关联.如果同时包含了两两种关联关系,就成为双向关联.在关系数据库中只有外键参照主键的关系.所以关系数据库实际上至支持一对一,或一对多的单向关系.在类于类之间的关系中.要算多对一关系和数据库中的外键参照主键关系最匹配了.因此如果使用单向关联从订单到客户的多对一单向关联,在订单类中就要定义一个客户的属性.表示这个订单属于哪个客户,而客户类就无需定义存放订单的集合属性了.下面写一个简单的例子.
//首先定义客户类
public class Customer implements Sreializable {
private Long id;
private String name;
//省略属性的访问方法
}
//然后定义订单类
public class Order implements Sreializable {
private Long id;
private String orderName;
private Customer customer;
//省略属性的访问方法,要注意的是Customer的访问方法.
}
Customer类的所有属性和CUSTOMERS表的所有属性一一对应,创建起来就比较简单了.下面主要看一下Order类的映射文件.
<property name="orderName" type="string">
<column name="ORDER_NAME" length="15"/>
</property>
因为customer属性是是Customer类型,而ORDERS表的CUSTOMER_ID是整数类型,是不匹配的.所以我们不能用普通的<property>元素来定义,而我们需要使用<many-to-one>元素来配置了.
<many-to-one name="customer" column="CUSTOMER_ID" class="包名.Customer" not-null="true"/>
<many-to-one>元素负责建立Order订单类的customer属性和数据库中的CUSTOMER_ID外键字段之间的映射.
name:设定映射文件的属性名
column:设定和持久化类对应的表的外键名
class:设定持久化类的属性的类型,这里指定具体的类,也就是主键存在的类
not-null:设定为true表示customer属性不允许为null,默认是false,这个属性会影响到bhm2ddl工具,会为ORDERS表的CUSTOMER_ID外键设置为不允许空的约束,但是不会影响到hbm2java工具生长java源代码.此外还会影响到Hibernate运行时的行为,在保存Order对象的时候会检查customer属性是否为null.用hbm2ddl编译之后得到的数据库文件如下:
create table CUSTOMERS (
ID bigint not null,
NAME varchar(15),
primary key (ID)
);
create table ORDERS (
ID bigint not null,
ORDER_NUMBER varchar(15),
CUSTOMER_ID bigint not null,
primary key (ID)
);
alter table ORDERS add index FK8B7256E516B4891C (CUSTOMER_ID),
add constraint FK8B7256E516B4891C foreign key (CUSTOMER_ID) references CUSTOMERS (ID);
看到结果我们可以简单的把<many-to-one>理解为在数据库中,创建外键的作用.上边这个例子就简单的演示了Hibernate映射的一对一关联关系,至于一对多的关联关系比这个稍微复杂一点.而且可以看出,当Hibernate持久化一个临时对象的时候,在默认的情况下它不会自动持久化关联其他临时对象,而是会抛出TransientObjectException异常.如果希望Hibernate持久化对象的时候也自动持久化说关联的对象,就要把<many-to-one>元素的cascade属性设置为save-update,表示级联操作的意思,cascade属性的默认值为none.当这个属性设置OK了.数据库就实现了级联保存更新的操作.
在类和类之间建好了关联关系之后,就可以方便的从一个对象得到它关联的对象.例如Customer customer=order.getCustomer();这样获得的了Customer对象了.但是如果想获得所有属于Customer客户的Order订单对象,就涉及到了一对多双向关联了.在内存中,从一个对象导航都另一个对象要比从数据库中通过一个字段查询另一个字段快的多的多,但是也给编程的时候带来了麻烦,随意修改一个对象就可能牵一发而动全身,所以说双向的关联比较复杂,但是类和类之间到底建立单向还是双向关联,这个要根据业务需求来决定.比如说业务需求根据指定客户查询客户所有订单,根据指定的订单,查询出发这个订单的客户.这个时候我们不妨用多对一双向关联处理.其实上边的例子的映射文件已经简历了客户和订单之间的一对多双向关联关系,只不过要在客户类中加一个集合的属性:
private set orders = new HashSet();
public set getOrders() {
return orders;
}
public void setOrders(Set orders) {
this.orders = orders;
}
有了orders属性,客户就可以通过getOrders()方法或者客户的全部订单了,Hibernate在定义这个集合属性的时候必须声明为接口类型,但是不光光是Set还有Map和List,这样可以提高程序的强壮性,就是说set方法接受的对象只要是实现了Set接口就OK.避免出现null值的现象.这里要注意的是hbm2java工具生成类的集合属性的代码时,不会给它初始化一个集合对象的实例,这里我们需要自己手动修改,当然不修改也是可以的.接下来还要在customer.hbm.xml映射文件里映射集合类型的orders属性,当然这个和order表的的<many-to-one>同理,所以不能通过普通的<property>元素来设置属性和字段的映射关系.要使用<set>元素来设置:
<set name="orders" cascade="save-update">
<key column="CUSTOMER_ID">
<one-to-many class="包名.Order">
</set>
name:设定类的属性名
cascade:设置为save-update表示级联保存更新,当保存或更新Customer类的时候会级联保存更新跟它关联的Order类.
<key>元素是用来设定跟持久化类关联的类的外键
<one-to-many>元素看起来很熟悉,哦是设置外键的元素反过来了.这里它是用来设置所关联的持久化类的.这里设置为和客户关联的订单Order类,这里表明这个属性里要存放一组Order类型的对象.
这个<set>元素是表示orders属性声明为set类型.
<set>元素还有一个inverse属性,这个方法主要是在给已存在数据库中的字段建立关联的时候很有用.就是说当我们获得数据库中的两个表的两条记录的对象customer客户对象和order订单对象(映射文件已经建立了他们类和类之间的关联,但外键的值为null的情况下)然后我们想建立这个客户对象和订单对象之间的关联,我们要先调用order.setCustomer(customer);然后在调用customer.getOrder().add(order);在Hibernate自动清理缓存的持久化对象的时候会提交两条SQL语句.进行了两个update操作.但是实际上只修改了一条记录.重复的执行SQL语句是会降低系统的运行效率的,当把inverse属性设置为true的时候,同样的操作就会合并到一条SQL语句执行了,inverse默认为false;
级联删除就很简单了,把cascade属性设置为delete,如果你删除了一个客户,程序就会先执行删除这个客户全部的订单的SQL语句,然后在删除这个客户,所谓删除一个持久化对象不是在内存中删除这个对象,而是删除数据库中相关的记录,这个对象依然在内存中,只不过由持久化状态转为临时状态,当这个对象的引用消失后,这个对象会被垃圾回收.但是如果我又想级联删除,还想级联保存,更新的时候应该怎么办呢?这个时候我们将cascade属性设置为all-delete-orphan就OK了.非常简单明了.我们还可以通过持久化类的customer.getOrder().rumove(order);解除关联.这里的操作表示获得客户订单的集合对象,然后从集合对象中删除order的订单,其实这种操作的意义不大,当我们不需要的这个订单的时候完全可以删除它,解除关联之后如果设置了级联删除属性,这个无用的记录也是要被删除的.其实解除关联就是把外键设为null.通常我们的外键都要约束不可以为空.
映射关联还有一种多对多的关联,是一种自身关联关系.就是同一张表.自己和自己的关联.比如说一张人表,地球人是人,美国人,中国人,日本人都属于地球人,中国人有分北京人,山东人.日本人也有下一级的比如东京人.下面设想如果日本人被消灭掉了,那么东京人也应该都被没有了吧,这就是一种关系,自身对自身的关联关系.这就有点类似树的结构了.下面用一个例子演示这种关系,代码来源于孙MM的<<精通Hibernate>>一书.
public class Category implements Serializable {
private Long id;
private String name;
private Category parentCategory;
private Set childCategories;
public Category(String name, mypack.Category parentCategory, Set childCategories) {
this.name = name;
this.parentCategory = parentCategory;
this.childCategories = childCategories;
}
public Category() {
}
public Category(Set childCategories) {
this.childCategories = childCategories;
}
public Category getParentCategory() {
return this.parentCategory;
}
public void setParentCategory(Category parentCategory) {
this.parentCategory = parentCategory;
}
public Set getChildCategories() {
return this.childCategories;
}
public void setChildCategories(Set childCategories) {
this.childCategories = childCategories;
}
//为了节省空间省略了id,name属性的访问方法
}
<hibernate-mapping >
<class name="mypack.Category" table="CATEGORIES" >
<id name="id" type="long" column="ID">
<generator class="increment"/>
</id>
<property name="name" type="string" >
<column name="NAME" length="15" />
</property>
<set
name="childCategories"
cascade="save-update"
inverse="true"
>
<key column="CATEGORY_ID" />
<one-to-many class="mypack.Category" />
</set>
<many-to-one
name="parentCategory"
column="CATEGORY_ID"
class="mypack.Category"
/>
</class>
</hibernate-mapping>
我觉得这种方式其实和上边的一对多,一对一关系一样,只不过两个用的都是同一个类罢了.看一下例子理解上应该很简单.
分享到:
相关推荐
Hibernate映射关联关系.pdf
对Hibernate映射关系详细总结,可以帮助你学习Hibernate知识
Hibernate4中映射关系图解。
hibernate,hibernate,hibernate,hibernate,hibernate,hibernate,hibernate,hibernate,hibernate,hibernate,hibernate,hibernate,hibernate,hibernate,包含4个说明文档,分别详细解说了hibernate关联映射的关联关系,...
【hibernate的关联关系映射】在Java持久化框架Hibernate中,关联关系映射是核心功能之一,它允许对象间的复杂关系与数据库中的表结构相匹配。在选课系统这个例子中,主要涉及到的对象包括课题(Course)、教师(Teacher...
本教程将详细讲解Hibernate中的关联关系映射配置,帮助你理解和掌握如何在Hibernate中设置不同类型的关联。 一、一对一(One-to-One)关联 在现实世界中,两个实体之间可能存在一对一的关系,例如一个人只有一个...
Hibernate_关联关系映射配置详解,希望能帮助广大java爱好者
### Hibernate实体关联关系映射详解 #### 一、引言 Hibernate作为一种强大的对象关系映射(Object Relational Mapping,简称ORM)框架,在Java开发领域扮演着极其重要的角色。它不仅简化了持久化层的开发工作,...
本主题将深入探讨Hibernate集合映射与关联关系,包括"student与Score的Map集合关系"、"student与class的多对一"以及"一对多映射"的概念。 首先,让我们理解一下Hibernate中的集合映射。在关系型数据库中,一个实体...
### Hibernate映射一对多关联关系 #### 知识点概览 - **概念解析**:一对多(One-to-Many)关联关系的概念及其在Hibernate中的实现方式。 - **域模型设计**:创建具有一个实体与多个实体关联的域模型。 - **关系...
在Java的持久化框架Hibernate中,多对多关联映射是一种常见的关系数据库模型映射方式,用于处理两个实体之间存在多个实例互相关联的情况。本文将深入探讨Hibernate如何实现多对多关联映射,并通过实际例子解析相关...
在深入探讨Hibernate关联关系映射分类之前,我们首先简要回顾一下Hibernate框架的基本概念。Hibernate是一种持久层框架,主要用于Java应用程序中的对象关系映射(ORM),它能够将面向对象的数据模型转换为数据库中的...
关于hibernate的关联操作 分享下
在Java企业级开发中,Hibernate是一个非常重要的对象关系映射(ORM)框架,它极大地简化了数据库操作。本文将深入探讨“hibernate关联映射实例”中的关键知识点,包括一对多、多对多和继承映射,这些都是Hibernate中...
### 用Hibernate映射继承关系 #### 14.1 继承关系树的每个具体类对应一个表 在Hibernate中映射继承关系时,一种常见的策略是将继承关系树的每个具体类映射到单独的数据库表中。这种方法称为**表/类映射**(Table/...
本篇文章将详细探讨在Hibernate中如何使用注解来处理各种关联关系,特别是`mappedBy`属性的用法。 首先,`@OneToMany`注解用于表示一对多的关联关系,比如一个班级可以有多个学生。在单向关联中,我们通常在拥有...
总之,Hibernate关联关系是理解其工作原理的关键,它使得Java对象和数据库记录之间的映射变得简单。通过练习,你可以掌握如何配置和使用这些关系,以及如何进行相关的查询操作,从而提升你的开发效率和代码质量。...
### Hibernate映射关联详解 #### 一、理解一对多双向关联关系 在关系型数据库设计中,一对多关联是常见的数据组织方式之一。而在面向对象编程语言中,这种关系则通常通过集合(如Set或List)来实现。本文将重点...