一对多和上文讲的多对一两种映射关系,其实就是站在相反的角度考虑同样的事情。

一对多和多对一映射原理是一样的,都在多的一端加入一个外键指向一的一端。也就是说,在关系数据库的表中,他们的表及表字段都是一样的。

他们的不同在于维护的关系:

          多对一维护的关系——多指向一的关系,如果维护了多指向一的关系,那么加载多的时候会把一加载上来。

         一对多维护的关系——一指向多的关系,如果维护了一指向多的关系,那么加载多的时候,会把一加载上来。

现在假如要用一对多映射描述学生和班级的关系。
1、hibernate单向一对多关联映射(Classes----->Student)
实体Classes。一对多关系,加载时需要在一的一端(classes端)加载上来多的一端(Student),所以实体Classes中需包含实体Student的引用。 [java] view plaincopyprint?
01.package com.lzq.hibernate;
02.import java.util.Set;
03.public class Classes {
04. private int id;
05. private String name;
06. private Set student;
07. 此处省略getter和setter方法
08.} 实体Student [java] view plaincopyprint?
01.package com.lzq.hibernate;
02.public class Student {
03. private int id;
04. private String name;
05. 此处省略getter和setter方法
06.}
映射文件Classes.hbm.xml。一对多关系中,需要在多的一端维护关系,所以在Classes端加入“one-to-many”标签维护关系。
[html] view plaincopyprint?
01.<?xml version="1.0"?>
02.<!DOCTYPE hibernate-mapping PUBLIC
03. "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
04. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
05.<hibernate-mapping>
06. <class name="com.lzq.hibernate.Classes" table="t_classes">
07. <id name="id">
08. <generator class="native" />
09. </id>
10. <property name="name" />
11. <!-- 集合映射set-->
12. <set name="student">
13. <!-- 设置classesid外键为非空字段-->
14. <key column="classesid" not-null="true"/>
15. <one-to-many class="com.lzq.hibernate.Student"/>
16. </set>
17. </class>
18.</hibernate-mapping> 映射文件Student.hbm.xml [html] view plaincopyprint?
01.<?xml version="1.0"?>
02.<!DOCTYPE hibernate-mapping PUBLIC
03. "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
04. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
05.<hibernate-mapping>
06. <class name="com.lzq.hibernate.Student" table="t_student">
07. <id name="id">
08. <generator class="native" />
09. </id>
10. <property name="name" />
11. </class>
12.</hibernate-mapping> 尽管我们完成映射,但是这样映射还存在一定的问题,看下面的加载: [java] view plaincopyprint?
01.public void testOne2ManyAdd() throws Exception {
02. Session session=null;
03. Transaction tx=null;
04. try {
05. session=HibernateUtils.getSession();
06. tx=session.beginTransaction();
07. Student student1=new Student();
08. student1.setName("张三");
09. session.save(student1);
10. Classes classes=new Classes();
11. classes.setName("提高班");
12. Set students=new HashSet();
13. students.add(student1);
14. classes.setStudent(students);
15. session.save(classes);
16. tx.commit();
17. } catch (Exception e) {
18. e.printStackTrace();
19. HibernateUtils.closeSession(session);
20. }
21. } 结果会抛PropertyValueException异常。原因很简单:我们在多的一端(Student)没有维护关系,也就是说,Student不知道自己是哪一个班的,所以我们在保存Student的时候关系字段classesid为null。这就限制了外键必须为允许非空,如果外键设置为“不能为空”,则无法进行保存。而我们这里对外键设置,所以才会抛出此异常。
那怎么解决该问题呢?当然,我们可以在Classes.hbm.xml配置中去掉“ not-null='true' ”,这样也可以保存,但是我们可以观察生成的SQL语句,此时进行了一条insert和update语句,显然,它实现插入了student信息,然后在更新的classesid字段。这种方式显然不友善。那么除了这种方式,还能不能用别的方式解决? 这应为此问题,才产生了双向的一对多的关联映射: 2、hibernate双向一对多关联映射(Classes<----->Student) 既然是双向一对多关联映射,那么一定要在多的一端(Student)加入一的一端(Classes)的引用,这样才能在多的一端(Student)进行存储和加载。 [java] view plaincopyprint?
01.package com.lzq.hibernate;
02.public class Student {
03. private int id;
04. private String name;
05.
06. private Classes classes;
07. 此处省略getter/setter方法
08.} 对应配置更改: [html] view plaincopyprint?
01.<?xml version="1.0"?>
02.<!DOCTYPE hibernate-mapping PUBLIC
03. "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
04. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
05.<hibernate-mapping>
06. <class name="com.lzq.hibernate.Student" table="t_student">
07. <id name="id">
08. <generator class="native" />
09. </id>
10. <property name="name" />
11. <!-- 此处需要与classes端的配置的字段保持一致-->
12. <many-to-one name="classes" column="classesid" />
13. </class>
14.</hibernate-mapping> 此外,既然双向一对多关联映射的产生是为了弥补单向一对多关联映射的缺陷,那么避免程序员编写程序仍然在一的一端(Classes)加载,我们可以采用反转技术,设置从Classes端加载失效: [html] view plaincopyprint?
01.<?xml version="1.0"?>
02.<!DOCTYPE hibernate-mapping PUBLIC
03. "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
04. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
05.<hibernate-mapping>
06. <class name="com.lzq.hibernate.Classes" table="t_classes">
07. <id name="id">
08. <generator class="native" />
09. </id>
10. <property name="name" />
11. <!--反转:设置从Classes端加入数据失效-->
12. <set name="student" inverse="true">
13. <key column="classesid" />
14. <one-to-many class="com.lzq.hibernate.Student"/>
15. </set>
16. </class>
17.</hibernate-mapping> 为什么多对一关联映射不存在单向一对多中的问题呢?如果你明白了上面所讲的,这个问题将很好回答。在多对一关联映射里面,由于关系是在多的一端进行维护的,加载的时候从多的一端进行加载,当然没有问题。 总结一下:在多对一关联映射中,如果用到,经常采用双向的方式来完成映射,弥补单向加载时的问题。

hibernate 映射 多对一的更多相关文章

  1. 【SSH系列】Hibernate映射 -- 多对多关联映射

         映射原理 在数据库学习阶段,我们知道,如果实体和实体之间的关系是多对多,那么我们就抽出来第三张表,第一张表和第二张表的主键作为第三表的联合主键,结合我们的hibernate,多对多关联,无论 ...

  2. Hibernate 映射多对多关联关系

    映射多对多,需要建立一张中间表 一共三张表,一个是 Category,一个是 Item,还有一个是 Categories_Items Categories_Items 作为中间表,其包含两个列,分别对 ...

  3. 【SSH进阶之路】Hibernate映射——多对多关联映射(八)

    上篇博文[SSH进阶之路]Hibernate映射——一对多关联映射(七),我们介绍了一对多关联映射,它是多对多关联映射的基础. 多对多映射是现实生活中最常见的映射,也是最容易理解的映射.废话少说,直接 ...

  4. (Hibernate进阶)Hibernate映射——多对多关联映射(八)

    多对多映射是现实生活中最常见的映射,也是最容易理解的映射.废话少说,直接开始. 映射原理 不论是单向关联还是双向关联都是通过第三张表,将两个表中的主键放到第三张做一个关联.用第三张表来解决可能会造成数 ...

  5. (Hibernate进阶)Hibernate映射——多对一单向关联映射(四)

    介绍基于基本映射的关联关系映射. 概念 基本映射是对一个实体进行映射,关联映射就是处理多个实体之间的关系,将关联关系映射到数据库中,所谓的关联关系在对象模型中有一个或多个引用. 分类 关联关系分为上述 ...

  6. Hibernate映射多对多双向关联关系(小案例)

    多对多双向关联关系(Project(工程)/Emp(员工)为案例): 步骤如下: 1.创建Project类,并需要定义集合类型的Emp属性 public class Project { //编号 pr ...

  7. 【SSH进阶之路】Hibernate映射——多对一单向关联映射(四)

    [SSH进阶之路]Hibernate基本原理(一) ,小编介绍了Hibernate的基本原理以及它的核心,採用对象化的思维操作关系型数据库. [SSH进阶之路]Hibernate搭建开发环境+简单实例 ...

  8. 【SSH系列】Hibernate映射-- 多对一单向关联映射

    在hibernate中非常重要的就是映射,在前面的博文中,小编简单的介绍了基本映射,基本映射是对一个实体进行映射,关联映射就是处理多个实体之间的关系,将关联关系映射到数据库中,所谓的关联关系在对象模型 ...

  9. Hibernate -- 映射多对多双向关联关系

    1. 示例代码: Student.java package cn.itcast.many2many; import java.util.HashSet; import java.util.Set; @ ...

随机推荐

  1. JS JQuery初始化

    (function($) {})(jQuery); 这种写法,申明一个匿名函数并立即调用 $(document).ready(function(){}); 文档全部加载完再执行 等同于$(functi ...

  2. 我使用中的Linux命令和快捷键(For Ubuntu)

    虽然自己工作一直都在MS的平台体系,自然很多的工作都需要在windows上完成,自己的电脑也一直使用windows操作系统,但是笔记本配置不是很好,导致装windows 8后,笔记本卡的难以忍受.想想 ...

  3. HttpClient读取ASP.NET Web API错误信息的简单方法

    在C#中,用HttpClient调用Web API并且通过Content.ReadAsStringAsync()读取响应内容时,如果出现500错误(InternalServerError),会得到一个 ...

  4. AutoMapper在ABP框架中的使用说明

    为了说明AutoMapper如何使用,我专门开设了一个专题来讲,如果您还没有查看该专题,请点击这里.既然系统地学习了AutoMapper,那么接下来就是该用它实战的时候了.今天,我们就来揭开AutoM ...

  5. 设计模式之美:Bridge(桥接)

    索引 别名 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):使用 Bridge 模式分离抽象部分和实现部分. 别名 Handle Body 意图 将抽象部分与它的实现部分分离,使它们 ...

  6. 如何带领一个Android开发团队

    1)重构,夜未眠 将框架从业务中剥离 如何提高开发效率 如何提高程序性能 单元测试 技术调研 代码版本管理 2)渠道包管理 自动打包工具 批量打渠道包的两种解决方案 定制渠道包的流程管理 3)稳定性, ...

  7. SQL范式小结

    说明:大多数初学者对于关系数据库中的范式很是头疼,我本人也是,所以今天又看了视频,总结了一下内容,尽量语言通俗易懂,少用专业术语以及概念. 首先要理解几个键值. 超键:在关系模式中,能唯一标识元组的属 ...

  8. 【Android】EventBus 源码解析

    EventBus 源码解析 本文为 Android 开源项目实现原理解析 中 EventBus 部分项目地址:EventBus,分析的版本:ccc2771,Demo 地址:EventBus Demo分 ...

  9. [jQuery学习系列二 ]2-JQuery学习二-数组操作

    前言 上一篇内容 已经对于Jquery 有了一些认识, 包括Jquery的选择器和DOM对象, 那么这一篇继续来看下Jquery中很实用的Jquery对于数组的操作. Jquery中对数组的操作大致有 ...

  10. Comet技术详解:基于HTTP长连接的Web端实时通信技术

    前言 一般来说,Web端即时通讯技术因受限于浏览器的设计限制,一直以来实现起来并不容易,主流的Web端即时通讯方案大致有4种:传统Ajax短轮询.Comet技术.WebSocket技术.SSE(Ser ...