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

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

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

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

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

现在假如要用一对多映射描述学生和班级的关系。
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. inotify 心得

    inotify 心得 一.inotify简介 inotify是Linux内核2.6.13 (June 18, 2005)版本新增的一个子系统(API),它提供了一种监控文件系统(基于inode的)事件 ...

  2. git 使用笔记

    git操作: git checkout 分支名称 // 切换分支git branch -a // 查看分支信息和当前分支 git pull // 将服务器所有代码下载到本地git merge orig ...

  3. Git 放弃修改

    1.文件较少 git checkout -- 文件名 2.文件较多 (直接版本回退) git reset --hard HEAD 在Git中,用HEAD表示当前版本,也就是最新的提交,上一个版本就是H ...

  4. Yii中设置时间分区

    在wamp环境下,运行一个Php yii的项目 出现问题: Use of undefined constant PRC - assumed 'PRC' 检测我的环境 PHP5.3 检测Php.ini中 ...

  5. 跟我一起学WCF(9)——WCF回调操作的实现

    一.引言 在上一篇文章中介绍了WCF对Session的支持,在这篇文章中将详细介绍WCF支持的操作.在WCF中,除了支持经典的请求/应答模式外,还提供了对单向操作.双向回调操作模式的支持,此外还有流操 ...

  6. ajax异步请求Response.Redirect重定向

    一个ajax异步请求报错->捕获异常->重定向错误提示页面.  一个简单的流程 结果一直搞不定.重定向无效.各种百度之. 后来突然想起 ajax的请求是不能在后台重定向的. 如果硬要重定向 ...

  7. node-webkit教程(9)native api 之Tray(托盘)

    node-webkit教程(9)native api 之Tray(托盘) 文/玄魂 目录 node-webkit教程(9)native api 之Tray(托盘) 前言 9.1  Tray简介 9.2 ...

  8. 冲刺阶段 day2

    day2 项目进展 今天本组五位同学聚在一起将项目启动,首先我们对项目进行了规划,分工,明确指出每个人负责哪些项目.由负责第一部分的组员开始编程,在已经搭建好的窗体内,对系部设置进行了编写,本校共六个 ...

  9. DataGridView绑定复杂实体(属性本身又是实体)

    今天我们来讨论下一个实体中某个属性又是实体的类型的集合绑定到DataGridView上的问题. 先来写一个Student类 public class Student { public int Stud ...

  10. Spring - 基于注解的组件扫描

    关于Spring的书籍都会花很大篇幅来讲解Spring如何注入各种bean的问题,非常令人头疼,自己在工作中还从来没有用到过. 所以就要跳过那些篇章,直接学习基于注解的组件扫描. 发现spring2是 ...