hibernate关联映射与集合映射详解

来源:互联网 发布:淘宝拍了不发货怎么办 编辑:程序博客网 时间:2024/05/23 11:56

一、单向多对一关系:

在多的一端加入:

<many-to-onename="classes"  lazy="false"fetch="join"/>

如果classes在实体类中是对象类型,则在多的一方中拥有外键也就是classes类映射出表的主键;如果classes在实体类中是对象类型,那么在<many-to-one/>中还要加 class属性用来指向外键表的实体类,同样多的一方中拥有外键(也就是外键表的主键

 多对一:XML配置

   <many-to-one name="propertyName"column="column_name“
class="ClassName“
cascade="cascade_style“
fetch="join|select“
update="true|false“
insert="true|false“
property-ref="propertyNameFromAssociatedClass“
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" />
配置属性说明如下:

 name: 实体类中属性名。
column (可选):外键字段名,其类型默认是通过反射得到属性类型,如果属性类型不是基本数据类型而是一个类的引用,那么该属性的类型是引用类的OID的类型它也可以通过嵌套的<column>元素指定。
class (可选 - 默认是通过反射得到属性类型): 关联的类的名字。
cascade(级联) (可选):指明哪些操作会从父对象级联到关联的对象。
fetch (可选 - 默认为 select):在外连接抓取(outer-joinfetching)和序列选择抓取(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): 指定这个属性在做更新时是否需要获得乐观锁定(optimisticlock)。 换句话说,它决定这个属性发生脏数据时版本(version)的值是否增长。
lazy (可选 - 默认为 proxy):默认情况下,单点关联是经过代理的,即此关联获取的是没有初始化代理对象存放在session缓存中作为持久化的状态,只有该属性在实例变量第一次被访问时,才会查询数据库并初始化该代理对象。lazy="no-proxy"指定此属性应该在实例变量第一次被访问时应该延迟抓取(fetchelazily)(需要运行时字节码的增强)。 lazy="false"指定此关联总是被预先抓取。
not-found (可选 - 默认为 exception): 指定外键引用的数据不存在时如何处理:ignore会将行数据不存在视为一个空(null)关联。
entity-name (可选): 被关联的类的实体名。
formula (可选): SQL表达式,用于定义computed(计算出的)外键值。

2.一对多关系(单向)

  在一端映射文件中加入:

       <set name="student" >

           <keycolumn="classesid"/>  <!--定义外键名称-->

         <one-to-many class="Student"/> <!--指出多的一方的实体类-->

        </set>

##上述定义外键名称的一般和“一方”的主键名相同,当然不相同也可,必须指出的是:外键存在于“多方”表中,且指向“一方”的主键。

key元素一定要写在<one-to-many/>的上面,否则出错

 3.一对多关系(双向):

 

             (1).在一端映射文件中加入:

             <set name="student" cascade="save-update"inverse="true">

                    <keycolumn="classesid"/>

                    <one-to-many class="Student"/>

             </set>

###

关于cascade和inverse的使用,请参看:http://blog.sina.com.cn/s/blog_7ffb8dd50101450c.html

             (2).在多的一端加入:

                    <many-to-onename="classes" column="classesid"></many-to-one>

 


 

二、一对一关系

1)一对一:XML配置

<one-to-one
name="propertyName"
class="ClassName"
cascade="cascade_style"
constrained="true|false"
fetch="join|select"
property-ref="propertyNameFromAssociatedClass"
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 exporttool中被使用).
fetch (可选 - 默认设置为选择): 在外连接抓取或者序列选择抓取选择其一.
property-ref: (可选)指定关联类的属性名,这个属性将会和本类的主键相对应。如果没有指定,会使用对方关联类的主键。
access (可选 - 默认是 property): Hibernate用来访问属性的策略。
formula (可选):绝大多数一对一的关联都指向其实体的主键。在一些少见的情况中,你可能会指向其他的一个或多个字段,或者是一个表达式,这些情况下,你可以用一个SQL公式来表示。(可以在org.hibernate.test.onetooneformula找到例子)
lazy (可选 - 默认为 proxy):默认情况下,单点关联是经过代理的。lazy="no-proxy"指定此属性应该在实例变量第一次被访问时应该延迟抓取(fetchelazily)(需要运行时字节码的增强)。lazy="false"指定此关联总是被预先抓取。注意,如果constrained="false",不可能使用代理,Hibernate会采取预先抓取!
entity-name (可选): 被关联的类的实体名。

1.   一对一外键关联

 以外键关联的重点是:两个实体各自有不相同的主键,但其中一个实体有一个外键引用了另一个实体的主键。   

 单向:(它其实就是一个多对一映射的一个特例,只是设置unique=”true”)

      在维护关系一端的映射文件中加入:<many-to-one name="card"unique="true"cascade="all"></many-to-one>

     双向:

在维护关系一端的映射文件中加入:<many-to-onename="card"unique="true"cascade="all"></many-to-one>

在另一段的映射文件中加入:

             <one-to-one name="users"property-ref="card"></one-to-one>

          由于    <one-to-onename>标签默认是找关联主键,所以在这里需要property-ref="card"配置关联属性。Cascade属性是级联的意思。

2.   一对一主键关联

 主键关联的重点是:关联的两个实体共享一个主键值。那么通过主键关联的两张表,其关联记录的主键值必须保持同步。这也就意味着,我们只需为一张表设定主键生成策略,而另一张表的主键与之共享相同的主键值通过“foreign”类型的主键生成策略与外键共享主键值

a)     单向

在维持关系一端的代码:

      <class name="com.Connection.oneTOone.User_pk">

             <idname="id">

                   <generatorclass="foreign">

                           <paramname="property">card_pk</param>

                    </generator>

             </id>

             <propertyname="name"unique="true"></property>

             <one-to-onename="card_pk" constrained="true"></one-to-one>

             

      </class>

设置<generatorclass="foreign">  class="foreign"这是特定的。

constrained="true" 设置该实体的主键是card_p的外键。  

 

 

 

b)    双向

在维持关系一端的代码:

      <classname="com.Connection.oneTOone.User_pk">

             <idname="id">

                   <generatorclass="foreign">

                           <paramname="property">card_pk</param>

                    </generator>

             </id>

             <propertyname="name"unique="true"></property>

             <one-to-onename="card_pk" constrained="true"></one-to-one>

            <!--constrained必须是“true”,以告知hibernate当前表主键上存在一个约束:t_passport表引用了t_user表的主键-->

      </class>

设置<generatorclass="foreign">  class="foreign"这是特定的。

constrained="true" 设置该实体的主键是card_p的外键。  

 

在维持关系的另一端的代码:

     加入:<one-to-onename="user_pk"/>

 

三、多对多关联映射

    

 单向:

   在维持关系一端的映射文件中加入:

<setname="popedoms" table="t_user_role">

<keycolumn="userid"/>

<many-to-manyclass="Popedom"column="popedomid"/>              

</set>

   它会再创建一张表:<keycolumn="userid"/>引用当前主键做为表的外键。<many-to-manyclass="com.hibernate.bean.Popedom"column="popedomid"/>,指定某表的主键做为它的外键。

 

双向:

     在两边都要加入相对的配置信息:

甲方:

<setname="popedoms"table="t_user_role">

<keycolumn="userid"/>

<many-to-manyclass="com.hibernate.bean.Popedom"column="popedomid"/>              

</set>

乙方:

   <set name="user"table="t_user_roles">

          <key column="popedomid"/>

          <many-to-manyclass="com.hibernate.bean.User"column="userid"/>

      </set>

其中要注意的是,两边配置信息的表名和字段名要一致。


四、集合映射

集合映射(set, list,array,bag, map)
<set name=”employees”>
      <key column=”depart_id”/>
      <one-to-many class=”Employee”/>
      <!-- <element type="string"column="name"/> -->
      <!--
         <composite-elementclass=”YourClass”>
            <property name=”prop1”/>
            <property name=”prop2”/>
         </composite>
      -->
</set>
集合映射(set,list, array,bag, map)
<list name=”employees”>
      <key column=”depart_id”/>
       <!-- index标签表示多的一方对应一的一方的索引位置  
     column属性表示数据库中存放数据的字段 
     index为关键字 避免跟关键字冲突 使用 `index`(tab键上面的,1左边的)或[index] 
      --> 

      <list-index column=”[index]”/>
      <one-to-many class=”Employee”/>
</list>
<arrayname=”employees” >
      <key column=”depart_id”/>
      <!—表中有单独的整型列表示list-index 
      <list-indexcolumn=”order_column”/>
      <one-to-many class=”Employee”/>
</array>
集合映射(set, list, array,bag, map)
<bag name="employees " order-by="iddesc">
      <keycolumn=”depart_id”/>         
      <one-to-many class=”Employee”/>
</bag>
<map name="employees ">
      <key column=”depart_id”/>
      <map-key type="string"column="name"/>
      <one-to-many class=”Employee”/>
</map>
   1、集合映射(set, list,array,bag, map)
这些集合类都是Hibernate实现的类和JAVA中的集合类不完全一样,set,list,map分别和JAVA中的Set,List,Map接口对应,bag映射成JAVA的List;这些集合的使用和JAVA集合中对应的接口基本一致;在JAVA的实体类中集合只能定义成接口不能定义成具体类,因为集合会在运行时被替换成Hibernate的实现。
集合的简单使用原则:大部分情况下用set,需要保证集合中的顺序用list,想用java.util.List又不需要保证顺序用bag。
   2、cascade和inverse (Employee – Department)
Casade用来说明当对主对象进行某种操作时是否对其关联的从对象也作类似的操作,常用的cascade:
   none,all,save-update ,delete,lock,refresh,evict,replicate,persist,
   merge,delete-orphan(one-to-many)。一般对many-to-one,many-to-many不设置级联,在<one-to-one>和<one-to-many>中设置级联。
inverse表“是否放弃维护关联关系”(在Java里两个对象产生关联时,对数据库表的影响),在one-to-many和many-to-many的集合定义中使用,inverse=”true”表示该对象不维护关联关系;该属性的值一般在使用有序集合时设置成false(注意hibernate的缺省值是false)。
   one-to-many维护关联关系就是更新外键。many-to-many维护关联关系就是在中间表增减记录。
    注:配置成one-to-one的对象不维护关联关系
0 0
原创粉丝点击