`
linbzh
  • 浏览: 71367 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

hibernate的映射处理

阅读更多

      最近闲着没事,就整理了hibernate的一些东西,供大家参考。
一、一对一关联在hibernate中的实现
一对一关联有两种实现方法:主键关联和外键关联。
主键关联是使两个表共享一个主键。比如,有表A和B,表A的主键为aid,那么表B

就把A的主键aid同时作为主键和外键使用。
A的映射文件:
<class name="A" table="A">
        <id name="aId" type="java.lang.String">
            <column name="aid"  length="10" />
            <generator class="guid"></generator>
        </id>
        <property name="aname" type="java.lang.String">
            <column name="aname" length="10" />
        </property>
        <one-to-one name="b" class="B" cascade="all"></one-to-one>
    </class>
cascade="all"表示级联操作,当cascade="false"时表示不进行级联操作。
<one-to-one name="b" class="B" cascade="all"></one-to-one>中的name="b"

在类A对应了属性b(类型为B);
B的映射文件:
<class name="B" table="B" >
<id name="bId" type="java.lang.String">
   <column name="bid" />
   <!-- 使用foreign的主键生成方式,引用A对象的主键作为B对象的主键 -->
     <generator class="foreign">
     <!-- 此a对应下面one-to-one的name名称一样 -->
     <param name="property">a</param>
    </generator>
</id>
<property name="bname" type="java.lang.String">
<column name="bname" length="20" />
</property>
<one-to-one name="a" class="A" constrained="true"></one-to-one>
</class>
<one-to-one name="a" class="A" constrained="true"></one-to-one>中的

name="a"在类B中对应了属性a(类型为A)
constrained="true"指明了B引用了A的主键作为外键,且是强制的一一对应关系。
使用外键关联,两个表都有各自的主键,比如,有表A和B,表A的主键为aid,那么表B就把A的主键aid同时作为外键使用。这种关联方法也可以用于一对多的关联。
A的映射文件:
<class name="A" table="A">
        <id name="aId" type="java.lang.String">
            <column name="aid" />
            <generator class="native"></generator>
        </id>
        <property name="aname" type="java.lang.String">
            <column name="aname" length="10" />
        </property>
        <one-to-one name="b" class="B" cascade="all" property-

ref="a"></one-to-one>
    </class>
A的映射文件中的property-ref="a"是必须的,它跟B的映射文件中name="a"的<many-to-one>对应。
B的映射文件:
<class name="B" table="B" >
<id name="bId" type="java.lang.String">
   <column name="bid"  length="10" />
     <generator class="native"></generator>
</id>
<property name="bname" type="java.lang.String">
<column name="bname" length="20" />
</property>
<many-to-one name="a" class="A" unique="true" column="aid"/>
</class>

B的映射文件中的<many-to-one name="a" class="A" unique="true"

column="aid"/>指定了B的一个外键aid,unique="true"为外键aid生成一个唯一的约束,并使有一对一的关联关系。

对于一对一的检索策略,一般使用预先抓取,当另一端比较少使用时,可以使用延迟加载。
A.hbm.xml的<one-to-one>节点的fetch属性,A.hbm.xml的<one-to-one>节点的constrained属性,B.hbm.xml的<class>节点的lazy属性,不同的配置对应了不同的检索策略:
预先:无,无,无
预先:join,false,任意
立即:select,任意,任意
延迟:任意,true,true

 

二、一对多关联在hibernate的单向关联实现
一对多单向关联,它存在了一定的缺陷。
在hibernate中,在“一”的一端使用集合来实现对应关系,把“一”的一端作为控制方,而“多”的一端作为被控制方,“多”的一端不需要任何特殊的配置。被控制方并不知道控制方是谁。例如,表A是“一”的一端,表B是“多”的一端。
A的映射文件:
<class name="A" table="a" >
        <id name="aId" type="java.lang.Integer">
            <column name="aid" />
            <generator class="native"></generator>
        </id>
        <property name="name" type="java.lang.String">
            <column name="name" length="10" />
        </property>
        <set name="bs" order-by="bid" cascade="all" fetch="join">
         <key column="aid" />
         <one-to-many class="B"></one-to-many>
        </set>
    </class>
order-by="bid"指定了排列顺序
<set ...></set>在类A中对应了属性bs(类型为HashSet<B>)
<one-to-many class="B"></one-to-many>指定了“多”的一端<key column="aid" />指定了“多”一端的外键。
B的映射文件:
<class name="B" table="b" >
        <id name="bId" type="java.lang.Integer">
            <column name="bid" />
            <generator class="native"></generator>
        </id>
        <property name="aId" type="java.lang.Integer">
            <column name="aid" />
        </property>
</class>
当A进行级联操作时,hibernate就会执行大量的sql语句,大大地影响了性能(可以在hibernate.cfg.xml设置<property

name="hibernate.jdbc.batch_size">30</property>实现批量更新,这个值一般取5~30)。如果把映射文件A中的<key column="aid" />设为<key column="aid" not-null="true" />则在级联删除时会抛出异常,因为在删除表B的记录之前会把aid设为NULL。

一对多关联的检索策略,优先考虑延迟加载,不同的<set/>的属性fetch,lazy的值,对于不同的检索策略
延迟:select,true
立即:select,false
预先:join,任意

 

三、一对多(多对一)关联在hibernate的双向关联实现
一对多(多对一)双向关联,在两端都知道各自的对方,解决了单向关联的缺陷。
一对多(多对一)双向关联,一般把“多”的一端作为控制方,如果把“一”的一端作为控制方的话,当加载“一”的一端的一条记录时就会加载“多”的一端相关的所有记录,这样就会影响性能。
例如,表A是“一”的一端,表B是“多”的一端。
A的映射文件:
<class name="A" table="a" >
        <id name="aId" type="java.lang.Integer">
            <column name="aid" />
            <generator class="native"></generator>
        </id>
        <property name="name" type="java.lang.String">
            <column name="name" length="10" />
        </property>
        <set name="bs" order-by="bid" cascade="all" lazy="true"

inverse="true">
         <key column="aid" />
         <one-to-many class="B"></one-to-many>
        </set>
    </class>
inverse="true",标识了被控制方一端,inverse="false"的一方为控制方,负责维护关联关系。
<set name="bs" ...></set>在类A中对应了属性bs(类型为java.util.HashSet<B>)
B的映射文件:
<class name="B" table="B" >
<id name="bId" type="java.lang.String">
   <column name="bid" />
     <generator class="native"></generator>
</id>
<property name="bname" type="java.lang.String">
<column name="bname" length="20" />
</property>
<many-to-one name="a" class="A" column="aid" cascade="none"/>
</class>
<many-to-one name="a" class="A" column="aid" cascade="none"/>指定了外键aid,name="a"对应了类B中的属性a(类型为A)inverse的默认值为false。

 

四、多对一关联在hibernate的单向关联实现
多对一单向关联。在hibernate中,在“多”的一端使用集合来实现对应关系,把“多”的一端作为控制方,而“一”的一端作为被控制方,“一”的一端不需要任何特殊的配置。被控制方并不知道控制方是谁。例如,表A是“一”的一端,表B是“多”的一端。
A的映射文件:
<class name="A" table="a" lazy="false">
        <id name="aId" type="java.lang.Integer">
            <column name="aid" />
            <generator class="native"></generator>
        </id>
        <property name="name" type="java.lang.String">
            <column name="name" length="10" />
        </property>
    </class>

B的映射文件:
<class name="B" table="b" >
        <id name="bId" type="java.lang.Integer">
            <column name="bid" />
            <generator class="native"></generator>
        </id>
        <many-to-one name="a" class="A" >
            <key column name="aid" />
        </property>
</class>
<many-to-one name="a" class="A" >对应了在类B的属性a(类型为A)可见,在“一”的一端相应的类A,并没有集合属性,类A不能获取“多”的一端对应的记录,这是多对一单向关联的特点。

对于多对一关联的检索策略,和一对一关联一样,也是首先考虑预先抓取,如果“一”的一端不常用,就用延迟加载检索策略。
B.hbm.xml的<many-to-one>节点的fetch属性,B.hbm.xml的<many-to-one>节点的lazy属性,A.hbm.xml的<class>节点的lazy属性,不同的配置对应不同的策略:
预先:join,任意,false
预先:无,无,false
延迟:任意,proxy,true
立即:任意,false,任意
立即:select,任意,false

 

五、多对多关联在hibernate的实现
如果两个表是多对多的关系,就需要一个中间表来实现多对多的对应关系。多对多关系是双向的。
<class name="A" table="a" >
        <id name="aId" type="java.lang.Integer">
            <column name="aid" />
            <generator class="native"></generator>
        </id>
        <property name="name" type="java.lang.String">
            <column name="name" length="10" />
        </property>
        <set name="bs" table="a_b" cascade="save_update"

inverse="false" lazy="true">
         <key column="aid" />
         <many-to-many class="B" column="bid"></many-to-many>
        </set>
    </class>
<set name="bs" ...></set>在类A中对应了属性bs(类型为HashSet<B>)
<key column="aid" />指定了在表a_b中的字段aid为表A的主键aid
<many-to-many class="B" column="bid"></many-to-many>指定了另一端

B的映射文件:
<class name="B" table="B" >
<id name="bId" type="java.lang.String">
   <column name="bid" />
     <generator class="native"></generator>
</id>
<property name="bname" type="java.lang.String">
<column name="bname" length="20" />
</property>
<set name="as" table="a_b" cascade="save_update" fetch="join"

lazy="true">
         <key column="bid" />
         <many-to-many class="A" column="aid"></many-to-many>
        </set>
</class>
<set name="as" ...></set>在类B中对应了属性as(类型为HashSet<A>)

多对多关联的检索策略,优先考虑延迟加载,不同的<set/>的属性fetch,lazy的值,对于不同的检索策略
延迟:select,true
立即:select,false
预先:join,任意

 

六、集合映射
有Map,集合中的每个元素都包好一对关键字和值对象,集合中的关键字不能重复;Set,集合中的每个元素都不会重复,可以是一个null对象,加入Set的元素都必须重新定义equals和hashCode方法,以便元素进行排序;List,是有序的排列

集合,允许元素重复,可以通过索引访问元素;Bag也是集合,允许元素重复,是无序的;idbag在bag在基础上添加了collection-id,是hibernate可以直接操作要更新的数据,提高效率。

每个集合映射值类型的配置都有相同之处:
<xxx name="" table=""><key column=""/><element column="" type=""/></xxx>

 

对于映射实体类型的配置:
bag和idbag没有映射实体类型;
Map和List有一个<index column="" type=""/>节点,Map的index节点是指定Map的key,List的index节点是维护排序的,正因为Map和List需要index节点,在设置inverse="true"时,保存集合中对象时,无法设置index的值,所以Map和List无法使用inverse="true"来实现的“多”端作为控制方,这样会影响性能;

 

集合的排列:
数据库读取时排列:在每个映射配置上加order-by属性,list不支持该属性;
读取后进行内存排列:使用sort属性,只有Map和set支持该属性。

 

值类型没有自己的生命周期,它依赖于附属的实体,随着实体的消亡而消亡;而实体类型作为一个独立的实体存在,有自己的生命周期。使用值类型不可以实现延迟加载会影响性能,而实体类型可以实现。

分享到:
评论

相关推荐

    生成hibernate映射文件工具

    hibernate映射文件是Java开发中用于对象关系映射(ORM)的重要组成部分,它将数据库表与Java类之间的关系进行定义,使得开发者无需编写大量的SQL语句,就能实现对数据库的操作。`生成hibernate映射文件工具`是为了...

    hibernate映射和查询

    **hibernate映射与查询** Hibernate 是一个流行的 Java 应用程序开发框架,它提供了一个持久层解决方案,简化了数据库操作。对于初学者来说,理解 Hibernate 的映射和查询机制是至关重要的,因为它们构成了 ...

    Hibernate 映射文件自动生成

    【压缩包子文件的文件名称列表】:“hibernate映射文件自动生成.doc”很可能是这篇博文的文档形式,其中详细介绍了具体的操作步骤、使用工具或者自定义脚本,以帮助开发者理解并应用自动化的映射文件生成过程。...

    Myeclipse生成Hibernate映射文件

    而MyEclipse作为一款强大的Java集成开发环境,提供了对Hibernate的良好支持,包括自动生成Hibernate映射文件的功能。本文将详细介绍如何在MyEclipse中创建和使用Hibernate映射文件。 首先,理解Hibernate映射文件...

    java根据实体类生成Hibernate映射文件

    在Java开发中,Hibernate是一个非常流行的ORM(对象关系映射)框架,它允许开发者使用面向对象...这个过程涉及到Java反射、XML处理以及对Hibernate映射机制的理解,对于深入掌握Java与数据库的交互具有重要的实践意义。

    Hibernate映射笔记

    ### Hibernate映射笔记详解 #### Hibernate映射文件与配置关系 Hibernate映射是ORM(对象关系映射)框架中的一项关键技术,它允许开发者在数据库表和Java对象之间建立映射关系,从而简化了数据访问层的开发工作。...

    hibernate映射枚举类型

    Hibernate通过`@Enumerated`注解来处理枚举映射。这个注解有两个可选的枚举值:`EnumType.ORDINAL`和`EnumType.STRING`。 - `EnumType.ORDINAL`:默认方式,按照枚举实例在枚举类中的位置(索引)作为数据库中的...

    常用 Hibernate 映射配置说明.doc

    ### 常用Hibernate映射配置详解 #### 1. hibernate-mapping节点解析 `hibernate-mapping`节点是Hibernate映射文件中的顶级节点,用于定义一系列配置选项,控制整个映射文件的行为和映射规则。这些配置包括数据库...

    Hibernate映射树形结构

    标题“Hibernate映射树形结构”指的是如何用Hibernate来存储和操作具有层级关系的数据。 1. **单表映射策略**: Hibernate可以使用单个表来存储树形结构,通过一个自增的`id`字段以及一个表示父节点的`parent_id`...

    Hibernate映射配置实例大全(详细总结)

    "Hibernate映射配置实例大全"是一个全面深入的资源,旨在帮助开发者理解和掌握如何有效地配置Hibernate以实现对象关系映射(ORM)。在这个文档中,我们将探讨各种关键的映射配置方法,以及相关的实例。 首先,我们...

    用Hibernate映射继承关系

    ### 用Hibernate映射继承关系 #### 14.1 继承关系树的每个具体类对应一个表 在Hibernate中映射继承关系时,一种常见的策略是将继承关系树的每个具体类映射到单独的数据库表中。这种方法称为**表/类映射**(Table/...

    Hibernate映射实例

    确保数据库与Hibernate映射文件一致,能正确地反映实体之间的关系。导入DBO到SQL Server数据库后,就可以通过Hibernate的Session接口进行CRUD(创建、读取、更新、删除)操作了。 在开发过程中,理解并熟练运用这些...

    hibernate映射文件生成数据库

    Hibernate映射文件,通常以`.hbm.xml`为扩展名,是Hibernate用来定义Java类与数据库表之间关系的配置文件。它包含了关于实体类与数据库表的字段对应、主键生成策略、关联关系等信息。通过这些映射文件,Hibernate...

    hibernate多对多关联映射

    在Java的持久化框架Hibernate中,多对多关联映射是一种常见的关系数据库模型映射方式,用于处理两个实体之间存在多个实例互相关联的情况。本文将深入探讨Hibernate如何实现多对多关联映射,并通过实际例子解析相关...

    Spring+Hibernate 自动映射

    标题中的“Spring+Hibernate 自动映射”是指在Java Web开发中,利用Spring框架与Hibernate ORM工具进行数据层的整合,实现对象关系映射(ORM)的自动化处理。这一技术结合了Spring的强大依赖注入(DI)和事务管理...

    hibernate映射篇

    Hibernate是Java领域中一款强大的对象关系映射框架,它允许开发者用面向对象的方式来处理数据库操作。在本篇文章中,我们将深入探讨Hibernate中的几种关联映射,包括多对一(Many-to-One)、一对一(One-to-One)...

    hibernate array 数组映射

    以上就是关于`hibernate array 数组映射`的主要内容,希望对理解Hibernate如何处理数组映射有所帮助。在实际开发中,根据具体需求选择合适的数据结构映射,可以极大地提高代码的效率和可维护性。

    Hibernate高级映射实例

    在处理复杂的关系时,合理的设计和映射可以避免数据冗余,提高数据一致性,并优化查询性能。 通过深入学习和实践Hibernate的高级映射,开发者能够更好地设计和实现数据模型,从而提升应用程序的性能和可维护性。...

    hibernate 映射关系学习入门 多对多实体映射

    通过源码学习,你可以深入了解Hibernate如何处理多对多关系的细节,从而更好地应用到实际项目中。在实际编程时,注意合理设计实体关系,确保数据的一致性和完整性,同时利用Hibernate的便捷性提高开发效率。

Global site tag (gtag.js) - Google Analytics