美文网首页Hibernate 菜鸟教程程序员
初识Hibernate之关联映射(二)

初识Hibernate之关联映射(二)

作者: Single_YAM | 来源:发表于2017-10-12 15:01 被阅读17次
 上篇我们介绍了关联映射的几种形式,有单向多对一,单向一对多,还有双向一对多。本篇接着介绍有关关联映射的其他几种映射方式,主要有以下几种:
  • 基于外键的单向一对一关联映射
  • 基于主键的单向一对一关联映射
  • 单向多对多关联映射

一、基于外键的单向一对一关联映射
具有一对一关联的表结构也是很常见的,比如:一个人对应于一张身份证。于是我们的person表会有一个外键关联到 idcard表的主键,只要这个外键列唯一即可保证person到idcard表的关系由多对一变为一对一,也就是说单向的一对一关联映射其实上也就是外键列唯一的多对一的关联映射。例如:

public class Person {
    private int id;
    private String name;
    private IdCard idcard;
    //省略get,set方法
}
public class IdCard {
    private int id;
    private String code;
    //省略get,set方法
}
<class name="Person" table="person">
    <id name="id">
        <generator class="native"/>
    </id>
    <property name="name"/>
    <many-to-one name="idcard" column="idcard_id" unique="true"/>
</class>

<class name="IdCard" table="idcard">
    <id name="id">
        <generator class="native"/>
    </id>
    <property name="code"/>
</class>

我们可以看到,几乎所有的代码和多对一关联映射都是差不多的,只不过在 many-to-one 元素中指定 unique="true",原来可以有多个具有相同外键值的记录映射到一的一端,现在指定外键值唯一之后,产生了唯一的一对一的关联映射。下面看看我们的测试代码:

//main 方法
Person p1 = new Person();
p1.setName("single");

IdCard idCard = new IdCard();
idCard.setCode("2345");

p1.setIdcard(idCard);

session.save(p1);
session.save(idCard);

我们分别创建两端的一个实例对象,然后由person端维护这种关联关系并将数据插入到数据库。看一眼结果:

这里写图片描述

这就是基于外键的单向一对一关联映射,与多对一的映射的唯一区别就在于,通过指定外键列唯一来让多的一端唯一,从而形成这种一对一的映射关系。

二、基于主键的单向一对一关联映射
所谓基于主键的映射就是指,其中的一张表的主键值依赖于另一张表的主键值。还是我们的人和身份证模型:

这里写图片描述

像这种IDCard表完全可以作为属性字段追加到person表的后面的情况(主键重复可覆盖),我们叫这种关联映射为基于主键的一对一关联映射。看看配置文件:

/*person实体类的映射文件的配置*/
<class name="Person" table="person">
    <id name="id" column="pId">
        <generator class="foreign">
            <param name="property">idCard</param>
        </generator>
    </id>
    <property name="name"/>
    <one-to-one name="idCard" constrained="true"/>
</class>
/*IDCard实体类的映射文件的配置*/
<class name="IdCard" table="idCard">
    <id name="id">
        <generator class="native"/>
    </id>
    <property name="code"/>
</class>

可以看到,主要的变化还是在于实体类person。首先我们指定他的主键不再自增,而是由外键约束到其他表,对应的其他表的类型则是自己实体类的idCard属性对应的表。one-to-one标签则配置了person类中的IdCard属性,便于我们在取数据的时候Hibernate填充数据到该属性中。下面我们添加数据到数据库中,通过查看输出的Sql语句了解Hibernate是如何为我们创建关联的。

Person person = new Person();
person.setName("single");

IdCard idCard = new IdCard();
idCard.setCode("23456789");
        
person.setIdCard(idCard);

session.save(idCard);
session.save(person);
这里写图片描述

显然,我们对于idcard表的主键指定了native自增,而对于person表的主键并没有指定自增,person表的主键依赖于idcard的主键。我们并不用指定person表的主键值,因为person会根据和自己关联的idcard表的主键来为自己的主键赋值。

三、单向多对多关联映射
多对多的表关联类型也是非常常见的,例如:

这里写图片描述

很常见的一个例子,一个学生可以有多个老师,同时一个老师也可以有多个学生,那么这就是很明显的多对多的关联映射。针对这种情况,一般来说数据库的表可以设计如下:

这里写图片描述

但是这种的表结构设计将会直接导致student表大量冗余,虽然解决了这种多对多的表级关联,但是存在大量冗余。Hibernate中处理这种多对多的关联关系是通过引入另一张表来实现对两个表主键的关联进而关联了两张表。

这里写图片描述

Student表和teacher表之间的多对多关联完全由connect表进行体现,各自表中数据不再大量冗余,这才是一种比较清晰的表结构设计。下面我们看代码:

public class Student {
    private int id;
    private String sName;
    private Set<Teacher> teachers = new HashSet<Teacher>(0);
    //省略get,set方法
}
public class Teacher {
    private int id;
    private String tName;
    //省略get,set方法
}

这是两张表对应的实体类,下面我们主要看映射文件的配置。

/*配置实体类Student*/
<class name="Student" table="student">
     <id name="id">
        <generator class="native"/>
     </id>
    <property name="sName"/>
    <set name="teachers" table="connect" cascade="save-update">
        <key column="stuId"></key>
        <many-to-many class="Teacher" column="tId"/>
    </set>
</class>
/*配置实体类Teacher*/
<class name="Teacher" table="teacher">
    <id name="id">
       <generator class="native"/>
    </id>
    <property name="tName"/>
</class>

Teacher实体类的配置并没有什么特殊需要解释的地方,而对于Student实体类的配置却稍有变化。其中的set标签就负责创建一张新表并负责关联两张表,table属性就是用于连接两张表主键值的表名(connect)。对于用于连接的表,有两个字段,一个是Student表的id,一个是teacher表的id,那么key标签就用于指定Student表id对应connect表中的名称,teacher表的id对应到connect表的名称则由many-to-many标签的column属性指定。下面我们插入多条数据:

这里写图片描述

显然,通过抽出connect表连关联两张表,对于Student和teacher表的表结构来说是更加简洁清晰的。

至此,有关Hibernate中关联映射的内容已经简单介绍完毕,虽然以后会更多的使用注解来配置这些映射关联,但是都是基于XML的,对于新手来说,学习XML配置关联映射是有助于理解注解配置。总结不到之处,望指出。

相关文章

  • 初识Hibernate之关联映射(二)

    基于外键的单向一对一关联映射 基于主键的单向一对一关联映射 单向多对多关联映射 一、基于外键的单向一对一关联映射具...

  • 初识Hibernate之关联映射(一)

    上篇文章我们对持久化对象进行的学习,了解了它的三种不同的状态并通过它完成对数据库的映射操作。但这都是基于单张表的操...

  • Hibernate数据持久化之集合的关联映射配置(08)

    Hibernate的关联映射 一 .关联映射的主要内容 1.1 关联映射的使用 普通类型的集合使用:例子,一个用户...

  • 初识Hibernate之继承映射

    前面的两篇文章中,我们介绍了两张表之间的各种相互关联映射关系,但往往我们也会遇到两张表甚至多张表之间共有着多个相同...

  • 一口一口吃掉Hibernate——多对多关联映射

    今天来说说Hibernate中的多对多关联映射,多对多关联映射涉及到单向映射和双向映射2种。 [java] vie...

  • Hibernate入门2-关联和映射

    Hibernate 快速入门2 - 关联映射和类继承 2 关联映射 我们知道两个表A、B的映射关系有 1-1, 1...

  • HIbernate第三-四次课

    第三次课 Hibernate的关联映射 many-to-ont关联 one-to-many关联 many-to-m...

  • Hibernate

    Hibernate 简介: Hibernate 是一个开源框架,它是对象关联关系映射的框架,它对 JDBC 做了轻...

  • Hibernate的关联映射

    首先我们了解一个名词ORM,全称是(Object Relational Mapping),即对象关系映射。ORM的...

  • Hibernate 关联关系映射

    本文包括:1、一对多结构的准备2、双向关联与单向关联3、级联保存4、级联删除5、cascade 属性——级联6、i...

网友评论

    本文标题:初识Hibernate之关联映射(二)

    本文链接:https://www.haomeiwen.com/subject/clfoyxtx.html