上篇我们介绍了关联映射的几种形式,有单向多对一,单向一对多,还有双向一对多。本篇接着介绍有关关联映射的其他几种映射方式,主要有以下几种:

  • 基于外键的单向一对一关联映射
  • 基于主键的单向一对一关联映射
  • 单向多对多关联映射

一、基于外键的单向一对一关联映射

     具有一对一关联的表结构也是很常见的,比如:一个人对应于一张身份证。于是我们的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之关联映射(二)的更多相关文章

  1. 初识Hibernate之关联映射(一)

    上篇文章我们对持久化对象进行的学习,了解了它的三种不同的状态并通过它完成对数据库的映射操作.但这都是基于单张表的操作,如果两张或者两张以上的表之间存在某种关联,我们又该如何利用持久化对象进行操作呢?本 ...

  2. Hibernate注解----关联映射注解以及课程总结详解----图片版本

    上一篇,记录了Hibernate注解----类级别注解以及属性注解详解 ,我们这一节主要讲解的是Hibernate注解----关联映射注解以及课程总结详解. 本节的主要内容: 第3章 关联映射注解 3 ...

  3. Hibernate的关联映射——双向1-N关联

    Hibernate的关联映射--双向1-N关联 对于1-N的关联,Hibernate推荐使用双向关联,而且不要让1的一端控制关联关系,而是用N的一端控制关联关系.双线的1-N关联和N-1关联是两种相同 ...

  4. Hibernate的关联映射——单向1-N关联

    Hibernate的关联映射--单向1-N关联 单向1-N关联的持久化类里需要使用集合属性.因为1的一端需要访问N的一端,而N的一端将以集合(Set)形式表现.从这个意义上来看,1-N(实际上还包括N ...

  5. Hibernate的关联映射——单向1-1关联

    Hibernate的关联映射--单向1-1关联 对于单向的1-1关联关系,需要在持久化类里增加代表关联实体的成员变量,并为该成员变量添加setter方法和getter方法.从持久化类的代码上看,单向1 ...

  6. Hibernate的关联映射——单向N-1关联

    Hibernate的关联映射--单向N-1关联 N-1是非常常见的关联关系,最常见的父子关系也是N-1关联,单向的N-1关联只需从N的一端可以访问1的一端. 为了让两个持久化类能够支持这种关联映射,程 ...

  7. Hibernate之关联映射(一对多和多对一映射,多对多映射)

    ~~~接着之前的Hibernate框架接着学习(上篇面试过后发现真的需要学习以下框架了,不然又被忽悠让去培训.)~~~ 1:Hibernate的关联映射,存在一对多和多对一映射,多对多映射: 1.1: ...

  8. Hibernate的关联映射关系

    一:多对一 <many-to-one 1.name:当前类的属性名(关联映射的类) 2.column:属性多对应的类的对应的表的外键(连接条件) 3.class:属性所对应的类的权限定名 4.n ...

  9. 初识Hibernate之继承映射

         前面的两篇文章中,我们介绍了两张表之间的各种相互关联映射关系,但往往我们也会遇到两张表甚至多张表之间共有着多个相同的字段.例如: 如图,student表和teacher表共同具有id,nam ...

随机推荐

  1. 三、nginx实现反向代理负载均衡

    1.反向代理 需求: 两个tomcat服务通过nginx反向代理 nginx服务器:192.168.101.3 tomcat1服务器:192.168.101.5 tomcat2服务器:192.168. ...

  2. 日志log4j配置详情,日志log具体到你想不到

    一.Log4j简介Log4j有三个主要的组件:Loggers(记录器),Appenders (输出源)和Layouts(布局). 1.LoggersLoggers组件在此系统中被分为五个级别:DEBU ...

  3. 如何部署 Calico 网络?- 每天5分钟玩转 Docker 容器技术(67)

    Calico 是一个纯三层的虚拟网络方案,Calico 为每个容器分配一个 IP,每个 host 都是 router,把不同 host 的容器连接起来.与 VxLAN 不同的是,Calico 不对数据 ...

  4. java课程设计——博客作业教学数据分析系统(201521123083 戴志斌)

    目录 一.团队课程设计博客链接 二.个人负责模块或任务说明 三.自己的代码提交记录截图 四.自己负责模块或任务详细说明 五.课程设计感想 (题外话,终于可以用markdown建目录) 一.团队课程设计 ...

  5. 201521123060《Java程序设计》第2周学习总结

    1. 本周学习总结 a.进一步熟悉了Eclipse的使用和java程序的编写: b.学习了java数据的基本类型:整数类型,浮点类型等: c.学习了算数运算符,赋值运算符,位运算符,关系运算符,逻辑运 ...

  6. 关于百度DNS的解析过程

    if现在我用一台电脑,通过ISP接入互联网,那么ISP就会分配给我一个DNS服务器(非权威服务器). now,我的computer向这台ISPDNS发起请求查询www.baidu.com. 首先,IS ...

  7. 201521123014 《Java程序设计》第11周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 2. 书面作业 Q1 互斥访问与同步访问 完成题集4-4(互斥访问)与4-5(同步访问) 1.1 除了使用sync ...

  8. delphi xe 3的EhLib 9.0 Build 9.0.033 Full Source安装

    1.打开项目文件 2.全选 3.编译和buil 4.添加路径

  9. HIbernate实体类注解配置

    一.类级别注解 1.@Entity(name="EntityName") 必须 name为可选,对应数据库中一的个表 2.@Table(name="",cata ...

  10. CacheConcurrencyStrategy五种缓存方式

    CacheConcurrencyStrategy有五种缓存方式:  CacheConcurrencyStrategy.NONE,不适用,默认  CacheConcurrencyStrategy.REA ...