`
glinux
  • 浏览: 25763 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

(Hibernate)cascade

阅读更多
利用关联关系操作对象:
数据对象之间的关联关系有一对一,一对多及多对多三种。在数据库操作中,数据对象之间的关联关系使用JDBC处理很困难。例如,当删除一个班级的信息时,还要删除该班级的所有学生的基本信息。如果直接使用JDBC执行这种级联操作,会非常繁锁。Hibernate通过把实体对象之间的关联关系及级联关系在映射文件中声明,比较简单地解决了这类级联操作问题。
一对一关联关系的使用:
一对一关联关系在实际生活中是比较觉的,例如学生与学生证的关系,通过学生证可以找到学生。一对一关联关系在Hibernate中的实现有两种方式,分别是主键关联和外键关联。
主键关联:
主键关联的重点是,关联两个实体共享一个主键值。例如student与card是一对一关系,它们在数据库中对应的表分别是t_student和 t_card。它们共用一个主键值ID,这个主键可由t_student或t_card表生成。问题是如何让另一张表引用已经生成的主键值呢?例如,t_student表未老先衰了ID的值,t_card表如何引用它?这需要在Hibernate的映射文件中使用主键的foreign生成机制!

为了表示Student与Card之间的一对一的关联关系,我们需要在它们各自的映射文件 中都要使用<one-to-one>标记!
一对一关系我在前面已经写过例子程序了,在这里仅给出两个映射文件。如下:
学生PO映射信息:
<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
    <class name="hibernate.PO.TStudent" table="t_student" lazy="true"><!--把类与表关联起来 -->
        <id name="id" type="java.lang.Integer">
            <column name="id"/>
            <generator class="increment" />
        </id>
        <property name="userName" type="java.lang.String">
            <column name="userName" length="20" />
        </property>
        <property name="cardId" type="java.lang.String">
            <column name="card_id" length="20" />
        </property>
        <property name="sex" type="java.lang.String">
            <column name="sex" length="2" />
        </property>
        <property name="age" type="java.lang.Integer">
            <column name="age" />
        </property>
        <one-to-one name="card" class="hibernate.PO.TCard" fetch="join" cascade="all" />
    </class>
</hibernate-mapping>
<!--
class元素的lazy属性设定为true,表示延迟加载,如果lazy设为false,则
表示立即加载。以下对这二点进行说明。
    立即加载:表示Hibernate在从数据库中取得数据组装好一个对象(如学生1)后,
            会立即再从数据库取得数据组装此对象所关联的对象(如学生证1)。
    延迟加载:表示Hibernate在从数据库中取得数据组装好一个对象(如学生1)后,
            不会立即再从数据库中取得数据组装此对象所关联的对象(如学生1),
            而是等到需要时,才会从数据库取得数据组装此关联对象。
<one-to-one>元素的cascade属性表明操作是否从父对象级联到被关联的对象,    它
的取得可以是以下几种:
    none:在保存,删除或修改当前对象时,不对其附属对象(关联对象)进行级联
          操作。它是默认值。
    save-update:在保存,更新当前对象时,级联保存,更新附属对象(临时对象,
          游离对象)。
    delete:在删除当前对象时,级联删除附属对象。
    all:所有情况下均进行级联操作,即包含save-update和delete操作。
    delete-orphan:删除和当前对象解除关系的附属对象。
<one-to-one>元素的fetch属性的可选值是join和select,默认是select。
当fetch属性设定为join时,表示连接抓取(Join fetching):Hibernate通过
在Select语句中使用outer join(外连接)来获得对象的关联实例或者关联集合。
当fetch属性设定为select时,表示查询抓取(Select fetching):需要另外发
送一条Select语句抓取当前对象的关联实体或集合。-->



学生证PO映射信息:
<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
    <class name="hibernate.PO.TCard" table="t_card" lazy="true">
        <id name="id" type="java.lang.Integer">
            <column name="id"/>
            <generator class="foreign">
                <param name="property">student</param>
            </generator>
        </id>
        <!-- id使用外键(foreign)生成机制,引用代号为student的对象
             的主键作为T_card表的主键和外键。同时student在下面的
             <one-to-one>中进行了定义 -->
        <property name="name" type="java.lang.String">
            <column name="name" length="20" />
        </property>
       
          
          <one-to-one name="student" class="hibernate.PO.TStudent" constrained="true" />        
          <!-- constrained="true"表示Card引用了student的主键作为外键。 -->
    </class>
</hibernate-mapping>



外键关联:
外键关联的要点是:两个实体各自有不同的主键,但其中一个实体有一个外键引用另一个实体的主键。例如,假设,Student和Card是外键关联的一对一关系们在数据库中相应的表分别如下:t_student表有一个主键ID,t_card表有一个主键ID和一个外键student_id,此外键对应 t_student表的主键ID,那么student的映射信息如上面一样不做改动,而Card的映射文件要做相应的改动。如下:
<hibernate-mapping>
    <class name="hibernate.PO.TCard" table="t_card" lazy="true">
        <id name="id" type="java.lang.Integer">
            <column name="id"/>
            <generator class="increment"/><!-- 不再是foreign了 -->                 
        </id>
        
        <property name="name" type="java.lang.String">
            <column name="name" length="20" />
        </property>
       
       <many-to-one name="student" column="student_id" class="hibernate.PO.TStudent" unique="true"/>
       <!-- 惟一的多对一,实际上变成一对一关系了 -->
         <!-- unique设为true表示使用DDL为外键字段生成一个惟一约束。
                 以外键关联对象的一对一关系,其本质上已经变成了一对多的双向关联,
                 应直接按照一对多和多对一的要求编写它们的映射文件。当unique为
                 true时实际上变成了一对一的关系。 -->
           
    </class>
</hibernate-mapping>


一对多关联关系的使用
一对多关系很觉,例如班级与学生的关系就是典型的一对多的关系。在实际编写程序时,一对多关系有两种实现方式:单向关联和双向关联。单向的一对多关系只需要在一方进行映射配置,而双向的一对多需要在关联的双方进行映射配置。下面以Group(班级)和Student(学生)为例讲解如何配置一对多的关系。
单向关联:
单向的一对多关系只需要在一方进行映射配置,所以我们只配置Group的映射文件:
<hibernate-mapping>
    <class name="hibernate.PO.Group" table="t_group" lazy="true">
        <id name="id" type="java.lang.Integer">
            <column name="id"/>
            <generator class="increment"/>                 
        </id>
        <!-- insert属性表示被映射的字段是否出现在SQL的INSERT语句中 -->
        <property name="name" type="java.lang.String" update="true" insert="true">
            <column name="name" length="20" />
        </property>
        
        <!-- set元素描述的字段对应的类型为java.util.Set类型。
            inverse用于表示双向关联中的被动一端。inverse的值
            为false的一方负责维护关联关系。
            sort排序关系,其可选值为:unsorted(不排序)。
                                  natural(自然排序)。
                                  comparatorClass(由某个实现了java.util.comparator接口的类型指定排序算法。)
            <key>子元素的column属性指定关联表(t_student表)的外键。
       -->
        <set name="students" 
             table="t_student" 
             lazy="true" 
             inverse="false" 
             cascade="all" 
             sort="unsorted">
        <key column="ID"/>
        <one-to-many class="hibernate.PO.TStudent"/>        
        </set>
    </class>
</hibernate-mapping>

双向关联:
如果要设置一对多双向关联关系,那么还需要在“多”方的映射文件中使用<many-to-one>标记。例如,在Group与Student一对多的双向关联中,除了Group的映射文件外还需要在Student的映射文件中加入如下代码:
 <many-to-one name="group"
                     class="Group"
                     cascade="none"
                     outer-join="auto"
                     update="true"
                     insert="true"
                     column="ID" />

inert和update设定是否对column属性指定的关联字段进行insert和update操作。
此外将Group.hbm.xml中<set>元素的inverse设置为true.

多对多关联关系的使用
Student(学生)和Course(课程)的关系就是多对多关系。在映射多对多关系时需要另外使用一个连接表(如Student_Course)。 Student_Course表包含二个字段:courseID和studentID。此处它们的映射文件中使用<many-to- many>标记,在Student的映射文件中加入以下描述信息:
 
<set name="courses" 
               table="student_course" 
               lazy="false" 
               inverse="false"
               cascade="save-update">
               <key column="studentID" />
           <many-to-many class="Course" column="CourseID"/>    
           </set>

相应的Course的映射文件中加入以下:
 <set name="students" 
               table="student_course" 
               lazy="false" 
               inverse="true"
               cascade="save-update">
               <key column="CourseID" />
           <many-to-many class="Student" column="StudentID"/>    
           </set>

添加关联关系:
首先编写一个程序来看看一个名为Bill的学生选择了什么课程:
//获取代表Bill的Student对象
        Student stu = (Student)session.createQuery("from Student s where s.name='Bill'").uniqueResult();
        List list = new ArrayList(stu.getCourses());
        for(int i = 0 ; i < list.size(); i++)
        {
            Course course = (Course)list.get(i);//取得Course对象
            System.out.println(course.getName());//打印出Bill所选课程的清单
        }

现在Bill还想chemistry课程,这对于程序员来说只是为Bill添加一个到chemistry的关联,也就是说在student_course表中新增加一条记录,而T_student和T_Course表都不用变更。
//获取代表Bill的Student对象
        Student stu = (Student)session.createQuery("from Student s where s.name='Bill'").uniqueResult();
        Course course = (Course)session.createQuery("from Course c where c.name='chemistry'").uniqueResult();
        //设置stu与course的关联关系
        stu.getCourses().add(course);
        course.getStudents().add(stu);

删除关联关系:
删除关联关系比较简单,直接调用对象集合的remove()方法删除不要的对象就可。例如:要从学生Bill的选课清单中删除politics和chemistry两门课,程序代码如下:
      
 //获取代表Bill的Student对象
        Student stu = (Student)session.createQuery("from Student s where s.name='Bill'").uniqueResult();
        Course course1 = (Course)session.createQuery("from Course c where c.name='politics'").uniqueResult();
        Course course2 = (Course)session.createQuery("from Course c where c.name='chemistry'").uniqueResult();
        stu.getCourse().remove(course1);//删除politics课程
        stu.getCourse().remove(course2);//删除chemistry课程

运行以上程序将从student_course表中删除这两条记录,但T_student和T_course表没有任何变化
分享到:
评论

相关推荐

    Hibernate cascade (级联).doc

    ### Hibernate级联(Cascade)详解 #### 一、概述 Hibernate 是一款强大的对象关系映射 (ORM) 框架,它允许开发人员将 Java 对象模型映射到数据库表,从而极大地简化了数据访问层的开发工作。在 Hibernate 中,...

    hibernate cascade 测试demo

    在Java的持久化框架Hibernate中,`cascade`是一个非常重要的概念,它涉及到对象关系映射(ORM)中的数据操作传播性。本测试Demo主要目的是帮助我们理解如何在Hibernate中使用`cascade`属性来处理关联对象的数据操作...

    Hibernate cascade在不同关联关系中的具体表现

    《Hibernate Cascade在不同关联关系中的具体表现》 Hibernate作为Java领域中广泛使用的对象关系映射(ORM)框架,极大地简化了数据库操作。其中,Cascade属性是Hibernate提供的一种强大的功能,它允许我们在操作一...

    hibernate_配置cascade_及all-delete-orphan.doc

    ### Hibernate中的Cascade选项详解 #### 一、概述 在Hibernate框架中,cascade选项提供了一种管理实体间关联的便捷方式,使得对一个实体的操作能够自动地应用到与之相关的其他实体上。这对于处理复杂的数据库关系...

    详解Hibernate cascade级联属性的CascadeType的用法

    详解Hibernate cascade级联属性的CascadeType的用法 cascade(级联) 级联在编写触发器时经常用到,触发器的作用是当 主控表信息改变时,用来保证其关联表中数据同步更新。若对触发器来修改或删除关联表相记录,必须...

    Hibenate cascade

    在Hibernate中,`cascade`和`inverse`是两个重要的概念,它们涉及到对象之间的关系管理和数据持久化。 **1. Hibernate Cascade** `cascade`属性主要用于控制对象间的级联操作。当在主对象上执行保存、更新、删除等...

    hibernate

    根据提供的文件信息,我们可以深入探讨Hibernate框架中的几个关键概念,特别是`fetch`, `lazy`, `cascade`, 和 `inverse`关键字的使用与理解。这四个概念在处理对象关系映射(ORM)时非常重要,尤其是在Java环境下...

    Hibernate many-to-many

    在这个"Hibernate Cascade"示例中,我们可能会看到如何配置这种关系,并且通过级联操作来管理这些关联对象的生命周期。 级联操作(Cascade)是Hibernate的一个特性,它允许我们将一个实体的操作(如保存、更新、...

    Hibernate中cascade与inverse属性详解

    Hibernate中cascade与inverse属性详解

    hibernate 级联(cascade和inverse)一对多

    在Java的持久化框架Hibernate中,级联操作(Cascade)和反转(Inverse)是两个重要的概念,它们主要用于管理对象关系模型中的关联关系。在一对多的关系中,这些特性可以帮助简化数据操作,提高代码的可读性和维护性...

    hibernate inverse和cascade的详细讲解

    ### Hibernate Inverse 和 Cascade 的详细讲解 #### 一、引言 在ORM(Object-Relational Mapping)领域,Hibernate作为一款流行的Java持久层框架,它提供了丰富的API和配置选项来帮助开发者实现对象与数据库表之间...

    Hibernate中cascade和inverse应用

    在 Hibernate 框架中,`cascade` 和 `inverse` 是两个重要的概念,它们主要用于管理对象之间的持久化关系,特别是涉及到一对一(one-to-one)、一对多(one-to-many)和多对多(many-to-many)关系时。这两个属性都...

    hibernate many-to-one(多对一)及 cascade(级联).doc

    ### Hibernate Many-to-One (多对一) 及 Cascade (级联) #### 一、Many-to-One(多对一) 在数据库设计中,实体之间的关系主要包括一对一、一对多、多对多等几种类型。而在ORM(对象关系映射)框架Hibernate中,...

    java 资料

    #### Hibernate cascade取值详解 - **Cascade Save-Update**: 当父对象被保存或更新时,其关联的所有子对象也将被保存或更新。 - **Cascade Delete**: 删除父对象时,所有关联的子对象也将被删除。 - **Cascade All-...

    学习过程中总结的一些问题!

    java,hibernate cascade设置,Oracle,jsp,Struts2 + jQuery 实现ajax,weblogic 自动部署 ,设计模式,js打印方法,搭建SVN服务端,jdk6+tomcat6+mysql5安装程序的制作,dwr备忘

    Hibernate_级联关系说明_-_关于cascade和inverse的用法

    在探讨Hibernate框架中的级联操作(cascade)与控制权反转(inverse)之前,我们需要先对Hibernate有一个基本的理解。Hibernate是一个开放源代码的对象关系映射(ORM)框架,它为Java应用提供了一种将对象模型映射到...

    错误及解决方案.pdf

    Hibernate中的Cascade属性指定了对持久化实体操作时,关联实体的级联操作类型。文档中提到的CascadeType.PERSIST表示对持久化操作的级联,CascadeType.MERGE表示对合并操作的级联。这些设置用于定义一个实体被保存或...

Global site tag (gtag.js) - Google Analytics