Hibernate3.6.2 关系映射(重点)

 

Hibernate 的映射关系,个人认为是非常重要的部分,映射关系的配置是在把握整体项目中所有实体之间的关联关系的基础上进行的,以前做项目时,在写这些映射文件时,总是对着 UML 图一个个仔仔细细的写。 Ok ,废话少说,上代码说明。

先说明几点

1 、关联关系的本质是将关联关系映射到数据库,所谓的关联关系是对象模型在内存中的一个或多个引用;

2 、关联关系分为单向和双向,单向即 AB 两个对象关联, A 能够查询得到对应关联的 BB 查询得不到关联的 A ,或者反过来。双向即 A 能够关联查询到 BB 也能关联查询到 A

3 、因为 Java 中的 list 是有顺序的 , 所有在 Hibernate 中一般常用 set , 所以在实体类中的对多的一方 , 其属性值用 set 集合而不用 list 集合 ;

下面来从关联数量上对:一对多、多对一、一对一、多对多配置进行说明,至于如果是单向,只要在一边配置关联关系,一边不配置,如果是双向则两边都配置关联关系即可。

一对多

		<class name="Company" table="tbl_company">
		<id name="id" type="int"><generator class="native" /><!-- 主键增值方式 -->
		</id>
		<property name="name"></property>

		<set name="employees" cascade="all" order-by="id desc">
			<key column="c_id">
			</key>
			<one-to-many class="Employee"/>
		</set>
		</class>

说明 :

1 、 在 set 中的 nameCompany 类中的属性名 ,order-by="id desc "id 排序 , column 为外键 , 为 many 的目标 ;

2 、<set> 元素的inverse 属性,在映射一对多的双向关联时,应该在one 方把inverse 属性设为true ,这样可提高应用性能

Inverse :控制反转,为true 表示反转,由它方负责;反之,不反转,自己负责,如果不设,onemany 两方都要负责控制,因此,会引发重复的sql 语句以及重复添加数据。

多对一

<class name="Employee" table="tbl_employee">
		<id name="id" type="int">	</id>
		<property name="name"></property>

		<many-to-one name="company" class="Company" cascade="all" column="c_id"></many-to-one>>	
</class>

说明:

1、注意这里的 column 如果在数据库中的这个字段与 java 类中的字段名一致,则 column 可以不用写 ,这里最好使用,因为如果不用 Hibernate 还要自动去识别,相对来说消耗了部分性能。

2、在many-to-one中的company是Employee中的字段,one的目标Company,注意这里的Employee类中要加Company对象

3、many-to-one元素的常用属性:

属性

含义和作用

必填

默认值

name

映射类属性名称

Y

class

关联类的完全限定名

N

column

关联的字段

N

not-null

设置关联的字段的值是否可以为空

N

false

lazy

指定关联对象是否使用延迟加载以及延迟加载的策略

N

proxy

fetch

设置抓取数据的策略

N

select

 

这里的抓取策略对 Hibernate 的性能提升也有很大帮助 , 详细的留在以后介绍。

 

4 、重要属性 ----cascade (级联),其意思是指定两个对象之间的操作联动关系,对一个对象执行了操作之后,对其指定的级联对象也需要执行相同的操作

all :代表在所有的情况下都执行级联操作

none :在所有情况下都不执行级联操作

save-update :在保存和更新的时候执行级联操作

delete :在删除的时候执行级联操作

若要多个操作都产生级联则:可以用 , 分开如: save-update,delete

 

在这里我们需要区分 inversecascade

Inverse :负责控制关系,默认为 false ,也就是关系的两端都能控制,但这样会造成一些问题,更新的时候会因为两端都控制关系,于是重复更新。一般来说有一端要设为 true

Cascade :负责控制关联对象的级联操作,包括更新、删除等,也就是说对一个对象进行更新、删除时,其它对象也受影响,比如我删除一个对象,那么跟它是多对一关系的对象也全部被删除。

1cascade 定义的是关系两端对象到对象的级联关系;而 inverse 定义的是关系和对象的级联关系。

2inverse 只对 set+one-to-many(many-to-many) 有效,对 many-to-one, one-to-one 无效。 cascade 对关系标记都有效。

3inverse 对集合对象整体起作用, cascade 对集合对象中的一个一个元素起作用,如果集合为空,那么 cascade 不会引发关联操作。

多对多

<class name="Student" table="tbl_student">
		<id name="id" type="int"><column name="ID" />
			<generator class="native" />
		</id>
		<property name="name" type="java.lang.String">
			<column name="NAME" />
		</property>

		<set name="cources" table="tbl_sc" cascade="all"><!-- 这里的cources是Student类中的对应属性 -->
			<key column="s_id"></key><!-- 注意这里的column是class所对应表中在sc表中对应的id -->
			<!-- 这里的column是 Cource在关系表中所对应的字段-->
			<many-to-many class="Cource" column="c_id"></many-to-many>
		</set>
		</class>

		<class name="Cource" table="tbl_cource">
		<id name="id" type="int"><column name="ID" />
			<generator class="native" />
		</id>
		<property name="name" type="java.lang.String">
			<column name="NAME" />
		</property>
		
		<set name="students" table="tbl_sc" cascade="all">
			<key column="c_id"></key>
			<many-to-many class="Student" column="s_id"></many-to-many>
		</set>
</class>

 

一对一

说明:

1 、有主键的 11 ,就是一个表中的主键 id 与另一个表中的主键 id 一一对应;

2 、有基于外键的 11 ,就是一个表的主键与另一个表中的外键一一对应,同时将这个表的外键设为唯一;

 

基于主键的一对一:

<class name="IdCard" table="tbl_idcard">
		<id name="id">
                        <!--id引用外部主键 -->
			<generator class="foreign">
				<param name="property">person</param>
			</generator>
		</id>
		<property name="idCard" column="IdCard" />
		<one-to-one name="person" constrained="true" cascade="all"></one-to-one>
	</class>

	<class name="Person" table="tbl_person">
		<id name="id" type="int">
			<generator class="native" />
		</id>
		<property name="name" />
		<one-to-one name="card" cascade="all"></one-to-one>
	</class>

说明:

one-to-one 标签 Hibernate 根据主键加载引用对象,把 person 中的主键拿到 idCard 表中进行查找,然后把查到的信息加载到引用对象中采用一对一主键约束,那么必须设置 constrained 属性,表示当前主键作为外键参照了该属性在一对一主键关联映射中默认问级联属性

基于外键的一对一:

<class name="Teacher" table="tbl_teacher">
		<id name="id" type="int"><column name="ID" />
			<generator class="native" />
		</id>
		<property name="name" type="java.lang.String">
			<column name="NAME" />
		</property>

		<!--unique="true"表示唯一,这是区别与多对一关系  -->
		<many-to-one name="cource" class="Cource" cascade="all" column="c_id" unique="true">
		</many-to-one>
	</class>

	<class name="Cource" table="tbl_cource">
		<id name="id" type="int"><column name="ID" />
			<generator class="native" />
		</id>
		<property name="name" type="java.lang.String">
			<column name="NAME" />
		</property>

		<!-- 注意这里的 property-ref="cource"是teacher表中的字段-->
		<one-to-one name="teacher" property-ref="cource" cascade="all"></one-to-one>
	</class>

 

项目中遇到的特殊关系的处理

1、上下级输出

<class name="Employee" table="tbl_employee">
	<id name="id" type="int">
		<generator class="native" />
	</id>
	<property name="name"></property>
	<many-to-one name="company" class="Company" cascade="all" column="c_id"></many-to-one>
	
	<!-- 多对一,即多个员工有一个上级领导 --><!-- not-found="ignore"当级联时没有此字段时则忽略 -->
<many-to-one name="supEmployee" class="Employee" cascade="all" column="sup_id" not-found="ignore"></many-to-one>
	<!-- 一对多,一个领导有多个员工 -->
	<set name="subEmployees" cascade="all"><!-- set中这里默认延迟加载为true,one to many中也是 -->
		<key column="sup_id">	</key>
		<one-to-many class="Employee"/>
	</set>
		
</class> 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值