hibernate关联映射与集合映射详解
(2012-10-27 10:29:29)
一、单向多对一关系:
在多的一端加入:
<many-to-one name="classes"
如果classes在实体类中是对象类型,则在多的一方中拥有外键(也就是classes类映射出表的主键); 如果classes在实体类中是对象类型,那么在<many-to-one />中还要加 class属性用来指向外键表的实体类,同样多的一方中拥有外键(也就是外键表的主键)
class="ClassName“
cascade="cascade_style“
fetch="join|select“
update="true|false“
insert="true|false“
property-ref="propertyNameFromAssociat
access="field|property|ClassName“
unique="true|false“
not-null="true|false“
optimistic-lock="true|false“
lazy="proxy|no-proxy|false“
not-found="ignore|exception“
entity-name="EntityName“
formula="arbitrary SQL expression“
node=“element-name|@attribute-name|element/@attribute|.”
embed-xml="true|false“
index="index_name“
unique_key="unique_key_id“
foreign-key="foreign_key_name" />
配置属性说明如下:
column (可选): 外键字段名,其类型默认是通过反射得到属性类型,如果属性类型不是基本数据类型而是一个类的引用,那么该属性的类型是引用类的OID的类型。它也可以通过嵌套的 <column>元素指定。
class (可选 - 默认是通过反射得到属性类型): 关联的类的名字。
cascade(级联) (可选): 指明哪些操作会从父对象级联到关联的对象。
fetch (可选 - 默认为 select): 在外连接抓取(outer-join fetching)和序列选择抓取(sequential select fetching)或者(join)中选择其一。
update, insert (可选 - 默认为 true) 指定对应的字段是否包含在用于UPDATE 和/或 INSERT 的SQL语句中。如果二者都是false,则这是一个纯粹的 “外源性(derived)”关联,它的值是通过映射到同一个(或多个)字段的某些其他属性得到 或者通过trigger(触发器)、或其他程序生成。
property-ref: (可选) 指定关联类的一个属性,这个属性将会和本外键相对应。 如果没有指定,会使用对方关联类的主键。
access (可选 - 默认是 property): Hibernate用来访问属性的策略。
unique (可选): 使用DDL为外键字段生成一个唯一约束。此外, 这也可以用作property-ref的目标属性。这使关联同时具有 一对一的效果。
not-null (可选): 使用DDL为外键字段生成一个非空约束。
optimistic-lock (可选 - 默认为 true): 指定这个属性在做更新时是否需要获得乐观锁定(optimistic lock)。 换句话说,它决定这个属性发生脏数据时版本(version)的值是否增长。
lazy (可选 - 默认为 proxy): 默认情况下,单点关联是经过代理的,即此关联获取的是没有初始化代理对象存放在session缓存中作为持久化的状态,只有该属性在实例变量第一次被访问时,才会查询数据库并初始化该代理对象。lazy="no-proxy"指定此属性应该在实例变量第一次被访问时应该延迟抓取(fetche lazily)(需要运行时字节码的增强)。 lazy="false"指定此关联总是被预先抓取。
not-found (可选 - 默认为 exception): 指定外键引用的数据不存在时如何处理: ignore会将行数据不存在视为一个空(null)关联。
entity-name (可选): 被关联的类的实体名。
formula (可选): SQL表达式,用于定义computed(计算出的)外键值。
2.一对多关系(单向):
##上述定义外键名称的一般和“一方”的主键名相同,当然不相同也可,必须指出的是:外键存在于“多方”表中,且指向“一方”的主键。
key元素一定要写在<one-to-many/>的上面,否则出错
###
关于cascade和inverse的使用,请参看:http://blog.sina.com.cn/s/blog_7ffb8dd50101450c.html
二、一对一关系
1)一对一:XML配置
<one-to-one
name="propertyName"
class="ClassName"
cascade="cascade_style"
constrained="true|false"
fetch="join|select"
property-ref="propertyNameFromAssociat
access="field|property|ClassName"
formula="any SQL expression"
lazy="proxy|no-proxy|false"
entity-name="EntityName"
node="element-name|@attribute-name|element/@attribute|."
embed-xml="true|false"
foreign-key="foreign_key_name" />
name: 属性的名字。
class (可选 - 默认是通过反射得到的属性类型):被关联的类的名字。
cascade(级联) (可选) 表明操作是否从父对象级联到被关联的对象。
constrained(约束) (可选) 表明该类对应的表对应的数据库表,和被关联的对象所对应的数据库表之间,通过一个外键引用对主键进行约束。 这个选项影响save()和delete()在级联执行时的先后顺序以及 决定该关联能否被委托(也在schema export tool中被使用).
fetch (可选 - 默认设置为选择): 在外连接抓取或者序列选择抓取选择其一.
property-ref: (可选) 指定关联类的属性名,这个属性将会和本类的主键相对应。如果没有指定,会使用对方关联类的主键。
access (可选 - 默认是 property): Hibernate用来访问属性的策略。
formula (可选):绝大多数一对一的关联都指向其实体的主键。在一些少见的情况中, 你可能会指向其他的一个或多个字段,或者是一个表达式,这些情况下,你可以用一个SQL公式来表示。 (可以在org.hibernate.test.onetooneformula找到例子)
lazy (可选 - 默认为 proxy): 默认情况下,单点关联是经过代理的。lazy="no-proxy"指定此属性应该在实例变量第一次被访问时应该延迟抓取(fetche lazily)(需要运行时字节码的增强)。 lazy="false"指定此关联总是被预先抓取。注意,如果constrained="false", 不可能使用代理,Hibernate会采取预先抓取!
entity-name (可选): 被关联的类的实体名。
1.
在维护关系一端的映射文件中加入:<many-to-one name="card" unique="true"cascade="all"></many-to-one>
在另一段的映射文件中加入:
2.
a)
在维持关系一端的代码:
设置<generator class="foreign">
constrained="true"
b)
在维持关系一端的代码:
设置<generator class="foreign">
constrained="true"
在维持关系的另一端的代码:
三、多对多关联映射
<set name="popedoms" table="t_user_role">
<key column="userid"/>
<many-to-many class="Popedom"column="popedomid"/>
</set>
双向:
甲方:
<set name="popedoms"table="t_user_role">
<key column="userid"/>
<many-to-manyclass="com.hibernate.bean.Popedom"column="popedomid"/>
</set>
乙方:
其中要注意的是,两边配置信息的表名和字段名要一致。
四、集合映射
集合映射(set, list, array,bag, map)
<set name=”employees” >
</set>
集合映射(set, list, array,bag, map)
<list name=”employees” >
</list>
<array name=”employees” >
</array>
集合映射(set, list, array,bag, map)
<bag name="employees " order-by="id desc">
</bag>
<map name="employees ">
</map>
这些集合类都是Hibernate实现的类和JAVA中的集合类不完全一样,set,list,map分别和JAVA中的Set,List,Map接口对应,bag映射成JAVA的List;这些集合的使用和JAVA集合中对应的接口基本一致;在JAVA的实体类中集合只能定义成接口不能定义成具体类, 因为集合会在运行时被替换成Hibernate的实现。
集合的简单使用原则:大部分情况下用set,需要保证集合中的顺序用list,想用java.util.List又不需要保证顺序用bag。
Casade用来说明当对主对象进行某种操作时是否对其关联的从对象也作类似的操作,常用的cascade:
inverse表“是否放弃维护关联关系”(在Java里两个对象产生关联时,对数据库表的影响),在one-to-many和many-to-many的集合定义中使用,inverse=”true”表示该对象不维护关联关系;该属性的值一般在使用有序集合时设置成false(注意hibernate的缺省值是false)。