• Hibernate的关联关系映射


    系统设计的实体间关系分别为:一对一,一对多(多对一),多对多

    一、一对多(多对一)

      一对多,多对一其实一样,只是站在不同的角度看,这种情况在多的一方添加一的一方的主键为外键。以学生Student和班级Grade为例介绍一对多关联关系在hibernate映射文件中的配置。

    Student.hbm.xml映射文件配置(多的一方有外键)

    <?xml version="1.0"?>
    <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    <!-- Generated 2017-8-9 15:15:47 by Hibernate Tools 3.5.0.Final -->
    <hibernate-mapping>
        <class name="com.imooc.entity.Student" table="STUDENT">
            <id name="sid" type="int">
                <column name="SID" />
                <generator class="increment" />
            </id>
            <property name="sname" type="java.lang.String">
                <column name="SNAME" />
            </property>
            <property name="sex" type="java.lang.String">
                <column name="SEX" />
            </property>
            <many-to-one name="grade" class="com.imooc.entity.Grade" fetch="join">
                <column name="gid" />
            </many-to-one>
        </class>
    </hibernate-mapping>

    Grade.hbm.xml映射文件配置

    <?xml version="1.0"?>
    <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    <!-- Generated 2017-8-8 23:10:39 by Hibernate Tools 3.5.0.Final -->
    <hibernate-mapping>
        <class name="com.imooc.entity.Grade" table="GRADE">
            <id name="gid" type="int">
                <column name="GID" />
                <generator class="increment" />
            </id>
            <property name="gname" type="java.lang.String">
                <column name="GNAME" />
            </property>
            <property name="gdesc" type="java.lang.String">
                <column name="GDESC" />
            </property>
            
            <!-- 一个班级对应多个学生,在班级映射文件中添加set属性,设置inverse为true则一方Grade不再进行维护关联信息(由多方维护)
                由于多方已知一方的信息,提高性能。设置级联属性cascade,则在保存班级信息会自动把学生信息(如果不存在)保存到数据库中-->
            <set name="students" table="STUDENT" inverse="true" lazy="true" cascade="save-update">
                <key>
                    <!-- 确定关联的外键列 -->
                    <column name="gid" />
                </key>
                <!-- 映射到关联类的属性 -->
                <one-to-many class="com.imooc.entity.Student" />
            </set>
        </class>
    </hibernate-mapping>

    二、一对一

      一对一其实是特殊的一对多关系,在任意一方引入对方的主键作为外键(实际使用非常少)。在映射文件中只需将多对一的unique设为true,以球队与地址为例说明。

    Address.hbm.xml映射文件配置

    <?xml version="1.0" encoding="utf-8"?>
    <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    <hibernate-mapping>
        <class name="com.suxiaolei.hibernate.pojos.Adress" table="adress">
            <id name="id" type="integer">
                <column name="id"></column>
                <generator class="increment"></generator>
            </id>
    
            <property name="city" column="city" type="string"></property>
            
            <one-to-one name="team" class="com.suxiaolei.hibernate.pojos.Team" cascade="all"></one-to-one>
    
        </class>
    </hibernate-mapping>

    Team.hbm.xml映射文件配置(在many-to-one 加入unique=“true”,并且将Address的id作为外键)

    <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    <hibernate-mapping>
        <class name="com.suxiaolei.hibernate.pojos.Team" table="team">
            <id name="id" type="integer">
                <column name="id"></column>
                <generator class="increment"></generator>
            </id>
    
            <property name="name" column="name" type="string"></property>
            
            <many-to-one name="adress" class="com.suxiaolei.hibernate.pojos.Adress" column="adress_id" unique="true"></many-to-one>
    
        </class>
    </hibernate-mapping>

    三、多对多

      多对多关系需要产生中间关系表,并引入两张表的主键作为外键。以project和employee为例说明

    project.hbm.xml映射文件配置

    <?xml version="1.0"?>
    <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    <!-- Generated 2017-8-9 15:55:46 by Hibernate Tools 3.5.0.Final -->
    <hibernate-mapping>
        <class name="com.imooc.entity.Project" table="PROJECT">
            <id name="proId" type="int">
                <column name="PROID" />
                <generator class="assigned" />
            </id>
            <property name="proName" type="java.lang.String">
                <column name="PRONAME" />
            </property>
            <!-- 多对多配置,相对于与两表有联系的新表进行配置 -->
            <set name="employees" table="proemp" cascade="save-update">
                <!-- 确定关联的外键列 -->
                <key>
                    <column name="rproid"></column>
                </key>
                <!-- 集合属性所对应的持久化类,以及关联的外键列 -->
                <many-to-many class="com.imooc.entity.Employee" column="rempid"></many-to-many>
            </set>
        </class>
    </hibernate-mapping>

    employee.hbm.xml映射文件配置

    <?xml version="1.0"?>
    <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    <!-- Generated 2017-8-9 15:55:46 by Hibernate Tools 3.5.0.Final -->
    <hibernate-mapping>
        <class name="com.imooc.entity.Employee" table="EMPLOYEE">
            <id name="empId" type="int">
                <column name="EMPID" />
                <generator class="assigned" />
            </id>
            <property name="empName" type="java.lang.String">
                <column name="EMPNAME" />
            </property>
             <!-- 多对多配置,相对于与两表有联系的新表进行配置 -->
            <set name="projects" table="proemp" inverse="true">
                   <!-- 确定关联的外键列 -->
                <key>
                    <column name="rempid"></column>
                </key>
                <!-- 集合属性所对应的持久化类,以及关联的外键 -->
                <many-to-many class="com.imooc.entity.Project" column="rproid"></many-to-many>
            </set>
        </class>
    </hibernate-mapping>

    四、关系中的反转与级联说明

      反转通过映射文件中对集合的inverse属性的设置,来控制关联关系。默认值为false,则关系两方都可以控制,可能在更新时会造成重复更新的情况,降低系统性能,在多对多关系中,如果两方都能控制并进行更新操作则可能报错。以project和employee为例,如果两方都添加另一方到set集合中,则中间表proemp会添加进两条相同的记录则会报错。

      通常的做法是在一对多关系中,将一的一方的inverse设为true(因为多的一方有外键可以知道一方的情况),由多的一方维护关联关系;在多对多关系中,在任意一方设置都可。

      级联是当一方进行保存,更新或删除操作时,其关联对象也执行相同操作。映射文件中通过对cascade属性设置控制是否对关联对象采用级联操作。

      在一对多关联关系执行保存操作时,如果不进行级联操作只保存Grade,则会报错,因为持久态对象grade关联了瞬时态对象Student,这种情况不允许保存,可设置grade映射文件的cascade="save-update",多对多关系也适用级联保存。

      级联删除:在一对多关系中,如果删除grade记录则与之相关的student的gid属性为null(未设置级联删除),使用级联删除可将与之相关的student都删除。

        多对多关系的级联删除也叫双向级联删除,删除某个学生时,与之关联的课程都要被删除,而与被关联课程相关的其他学生也需要删除。

  • 相关阅读:
    JS阻止鼠标滚动
    仿淘宝订单列表下标指针
    自己动手模拟百分百<select>下拉列表
    专门用来存地址
    JS手动触发事件,转载
    刷新页面让显示区域回到顶部
    解决表格边框问题
    读书笔记 effective c++ Item 43 了解如何访问模板化基类中的名字
    读书笔记 effective c++ Item 42 理解typename的两种涵义
    读书笔记 effective c++ Item 41 理解隐式接口和编译期多态
  • 原文地址:https://www.cnblogs.com/simple96/p/7327772.html
Copyright © 2020-2023  润新知