SSH——Hibernate初学者之旅(三)

      上次我们说到了hibernate映射关系中的一对一关系,可是,我们知道,在实际应用中,我们最常遇到的还是一对多的关系。所以,今天我们来看看一对多关系的映射是怎么做到的。

一、实体

//人
public class Person1nfk implements Serializable {
    private int personid;
    private String name;
    private int age;
    private Set addresses=new HashSet();
//地址
public class Address1nfk implements Serializable {
    private int addressid;
    private String addressdetail;

二、外键–关联映射法

1、单向

  • 一对多

一个人(Person)对应多个地址(Address),比如家庭地址、公司地址。

<hibernate-mapping>
    <class name="com.lavasoft.dx._1_n_fk.Person1nfk" table="PERSON_1nfk">
        <id name="personid">
            <generator class="identity"/>
        </id>
        <property name="name"/>
        <property name="age"/>
        <!--映射集合属性,关联到持久化类,inverse="false"表示主控端在Person1nfk端,lazy="false"表示不采用延迟加载-->
        <set name="addresses"
             table="ADDRESS_1nfk"
             cascade="all"
        >
            <!--确定关联的外键列-->
            <key column="personid"/>
            <!--用以映射到关联类属性-->
            <one-to-many class="com.lavasoft.dx._1_n_fk.Address1nfk"/>
        </set>
    </class>
</hibernate-mapping>
<hibernate-mapping>
    <class name="com.lavasoft.dx._1_n_fk.Address1nfk" table="ADDRESS_1nfk">
        <id name="addressid">
            <generator class="identity"/>
        </id>
        <property name="addressdetail"/>
    </class>
</hibernate-mapping>

      解说1: inverse的真正作用就是指定由哪一方来维护之间的关联关系。当一方中指定了“inverse=false”(默认),那么那一方就有责任负责之间的关联关系。
      解说2: Set集合属于无序集合,映射时只需指定Set集合的key(外键列)、element(元素列),以外键列、元素列(非空)作为联合主键;元素列为空时,Set集合表没有主键。


  • 多对一

多个人(Person)对应一个地址(Address)。

<hibernate-mapping>
    <class name="com.lavasoft.dx._n_1_fk.Personn1fk" table="PERSON_n1fk">
        <id name="personid">
            <generator class="identity"/>
        </id>
        <property name="name"/>
        <property name="age"/>
        <!--用来映射关联PO column是Address在该表中的外键列名,inverse="false"表示主控端在Person1nfk端-->
        <many-to-one name="addressn1fk" column="addressId"/>
    </class>
</hibernate-mapping>
<hibernate-mapping>
    <class name="com.lavasoft.dx._n_1_fk.Addressn1fk" table="ADDRESS_n1fk">
        <id name="addressid">
            <generator class="identity"/>
        </id>
        <property name="addressdetail"/>
    </class>
</hibernate-mapping>

2、双向

  • 一对多

一个人(Person)对应多个地址(Address)。

<hibernate-mapping>
    <class name="com.lavasoft.sx._1_n_fk.Person1nfk_sx" table="PERSON_1nfk_sx">
        <id name="personid">
            <generator class="identity"/>
        </id>
        <property name="name"/>
        <property name="age"/>
        <!--映射集合属性,关联到持久化类-->
        <set name="addresses" inverse="true" cascade="all">
            <!--column用于指定外键列名-->
            <key column="personid" not-null="true"/>
            <!--映射关联类-->
            <one-to-many class="com.lavasoft.sx._1_n_fk.Address1nfk_sx"/>
        </set>
    </class>
</hibernate-mapping>
<hibernate-mapping>
    <class name="com.lavasoft.sx._1_n_fk.Address1nfk_sx" table="ADDRESS_1nfk_sx">
        <id name="addressid">
            <generator class="identity"/>
        </id>
        <property name="addressdetail"/>
        <!--映射关联属性,column属性指定外键列名-->
        <many-to-one name="person1nfk"
            class="com.lavasoft.sx._1_n_fk.Person1nfk_sx"
            fetch="select"
            cascade="save-update">
            <column name="personid" not-null="true"/>
        </many-to-one>
    </class>
</hibernate-mapping>

      解说1: inverse=true的含义: 由双向关联另一方维护该关联,己方不维护该关联(只能进行查询操作)。在上代码中,由Address1nfk_sx类这方维护该关系。
      解说2:
      Inverse:负责控制关系,默认为false,也就是关系的两端都能控制,但这样会造成一些问题,更新的时候会因为两端都控制关系,于是重复更新。一般来说有一端要设为true。
      Cascade:负责控制关联对象的级联操作,包括更新、删除等,也就是说对一个对象进行更新、删除时,其它对象也受影响,比如我删除一个对象,那么跟它是多对一关系的对象也全部被删除。
      解说3: fetch抓取策略:默认是fetch=”select”,另外发送一条select语句抓取当前对象关联实体或集合;当配置fetch=”join”,hibernate会通过select语句使用外连接来加载其关联实体或集合,此时lazy会失效

三、连接表–关联映射法

1、单向

  • 一对多

一个人(Person)对应多个地址(Address),比如家庭地址、公司地址。

<hibernate-mapping>
    <class name="com.lavasoft.dx._1_n_tab.Person1ntab" table="PERSON_1ntab">
        <id name="personid">
            <generator class="identity"/>
        </id>
        <property name="name"/>
        <property name="age"/>
        <!--映射集合属性,join_1ntab是连接表表名-->
        <set name="addresses"
             table="join_1ntab"
                >
            <!--“column="personid"”确定PERSON_1ntab表关联到连接表的外键列名-->
            <key column="personid"/>
            <!--“column="addressid"”关联PERSON_1ntab表的Address1ntab对象的id在连接表中的列名-->
            <!--“unique="true"表示1-N,Person1ntab是1,Address1ntab是多”-->
            <many-to-many
                    column="addressid"
                    unique="true"
                    class="com.lavasoft.dx._1_n_tab.Address1ntab"/>
        </set>
    </class>
</hibernate-mapping>
<hibernate-mapping>
    <class name="com.lavasoft.dx._1_n_tab.Address1ntab" table="ADDRESS_1ntab">
        <id name="addressid">
            <generator class="identity"/>
        </id>
        <property name="addressdetail"/>
    </class>
</hibernate-mapping>
  • 多对一

多个人(Person)对应一个地址(Address)。

<hibernate-mapping>
    <class name="com.lavasoft.dx._n_1_tab.Personn1tab" table="PERSON_n1tab">
        <id name="personid">
            <generator class="identity"/>
        </id>
        <property name="name"/>
        <property name="age"/>
        <!--使用join元素显式确定链接表-->
        <join table="join_n1tab">
            <!--映射关联所用的外键-->
            <key column="personid"/>
            <many-to-one name="addressn1tab"/>
        </join>
    </class>
</hibernate-mapping>
<hibernate-mapping>
    <class name="com.lavasoft.dx._n_1_tab.Addressn1tab" table="ADDRESS_n1tab">
        <id name="addressid">
            <generator class="identity"/>
        </id>
        <property name="addressdetail"/>
    </class>
</hibernate-mapping>

2、双向

<hibernate-mapping>
    <class name="com.lavasoft.sx._1_n_tab.Person1ntab_sx" table="PERSON_1ntab_sx">
        <id name="personid">
            <generator class="identity"/>
        </id>
        <property name="name"/>
        <property name="age"/>
        <!--映射集合属性,关联到持久化类-->
        <!--table="join_1ntab_sx"指定了连接表的名字-->
        <set name="addresses"
             table="join_1ntab_sx"
             cascade="all">
            <!--column="personid"指定连接表中关联当前实体类的列名-->
            <key column="personid" not-null="true"/>
            <!--unique="true"表示当前实体类是"1",不是"n"-->
            <many-to-many column="addressid"
                          unique="true"
                          class="com.lavasoft.sx._1_n_tab.Address1ntab_sx"/>
        </set>
    </class>
</hibernate-mapping>
<hibernate-mapping>
    <class name="com.lavasoft.sx._1_n_tab.Address1ntab_sx"
           table="ADDRESS_1ntab_sx">
        <id name="addressid">
            <generator class="identity"/>
        </id>
        <property name="addressdetail"/>
        <!--映射关联属性,column属性指定外键列名-->
        <join   table="join_1ntab_sx"
                inverse="true"
              optional="true">
            <key column="addressid"/>
            <many-to-one name="person1ntab_sx"
                         column="personid"
                         cascade="all"
                         not-null="true"/>
        </join>
    </class>
</hibernate-mapping>

总结:

      我们通过一对多映射关系的学习,了解了one-to-many和many-to-one的使用,那么下次我们将继续介绍many-to-many的映射关系。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值