【SSH 基础】浅谈Hibernate关系映射(3)

继上篇博客

一对多关联映射(单向)

上面我们介绍了多对一,我们反过来看一对多不就是多对一吗?那还用再进行不同的映射吗?有什么区别吗?一对多和多对一映射原理是一致的,存储是同样的。也就是生成的数据库的表是一样的。他们之间不同的是维护的关系不同。

他们之间不同点是维护的关系不同

*多对一维护的关系是:多指向一的关系。有了此关系,载入多的时候能够将一载入上来。

*一对多维护的关系是:一指向多的关系。有了此关系,在载入一的时候能够将多载入上来。

一个班级有多个学生,通过班级能够看到学生信息。

Classes的映射关系

<hibernate-mapping>
	<class name="com.bjpowernode.hibernate.Classes">
		<id name="id">
			<generator class="native"></generator>
		</id>
		<property name="name"></property>
		<set name="students">
			<key column="classesid"/>
			<one-to-many class="com.bjpowernode.hibernate.Student"/>
		</set>
	</class>
</hibernate-mapping>

Student的映射关系

<hibernate-mapping>
	<class name="com.bjpowernode.hibernate.Student">
		<id name="id">
			<generator class="native"></generator>
		</id>
		<property name="name"></property>
	</class>

</hibernate-mapping>

再看保存的代码:给班级设置学生,而由于学生维护关系。就要在学生端保存班级id--会带来什么问题?

public void testSave2(){
		Session session=null;
		try{
			session=HibernateUtils.getSession();
			session.beginTransaction();

			Student student1=new Student();
			student1.setName("张三");
			session.save(student1);

			Student student2=new Student();
			student2.setName("李四");
			//保存学生
			session.save(student2);

			Classes classes=new Classes();
			classes.setName("动力节点");

			Set students=new HashSet();
			students.add(student1);
			students.add(student2);

			classes.setStudents(students);
			session.save(classes);
			session.getTransaction().commit();

		}catch(Exception e){
			e.printStackTrace();
			session.getTransaction().rollback();
		}finally{
			HibernateUtils.closeSession(session);
		}
	}

在保存数据时,会存在这么一个时刻:so?带来的问题

1,从班级能看到学生。是班级来维护关系,不是学生来维护关系,学生不知道自己是哪个班。所以在保存学生的时候,班级id不知道。为了更新学生是哪个班级的要发出非常多update语句来告诉学生是哪个班级的。

2。当我们设置classesidnot-null=“true”时,则将无法保存数据,解决的方法我们改为双向关联映射。

一对多关联映射(双向)

为了解决一对多单向可能存在的问题,我们採用双向一对多。每一方都能维护对方。

而不是需求驱动

一对多双向关联映射方式:

*在一的一端的集合上採用<key>标签。在多的一端增加一个外键。

*在多的一端採用<many-to-one>的标签

!~注意<key>标签和<many-to-one>标签增加字段保持一致,否则会产生数据混乱。

Classes映射文件

<hibernate-mapping>
	<class name="com.bjpowernode.hibernate.Classes">
		<id name="id">
			<generator class="native"></generator>
		</id>
		<property name="name"></property>
		<set name="students" inverse="true">
			<key column="classesid"/>
			<one-to-many class="com.bjpowernode.hibernate.Student"/>
		</set>
	</class>
</hibernate-mapping>

Student映射文件

<hibernate-mapping>
	<class name="com.bjpowernode.hibernate.Student">
		<id name="id">
			<generator class="native"></generator>
		</id>
		<property name="name"></property>
		<many-to-one name="classes" column="classesid"></many-to-one>
	</class>
</hibernate-mapping>

注意:Inverse属性

1、Inverse中文意思为相反的,反转。在hibernate中inverse能够用在一对多和多对多双向关联上,inverse默认是false。为false的时候表示本端能够维护关系,假设inverse为true,则本端不能维护关系。会交给还有一端维护关系。本端失效,所以在一对多关联映射我们通常在多的一端维护关系。让一的一端失效。

2、Inverse是控制方向上的反转,仅仅影响存储。

比較一对多单向和双向映射,从存储结构上看没有什么差别,可是从配置文件上看。一对多双向关联的配置文件里在多的一端的配置文件上存在<many-to-one>相关配置,即保证多对一的映射。

下篇继续。

时间: 2024-10-09 22:56:48

【SSH 基础】浅谈Hibernate关系映射(3)的相关文章

浅谈Hibernate关系映射(3)

继上篇博客 一对多关联映射(单向) 上面我们介绍了多对一,我们反过来看一对多不就是多对一吗?那还用再进行不同的映射吗?有什么差别吗?一对多和多对一映射原理是一致的,存储是相同的,也就是生成的数据库的表是一样的,他们之间不同的是维护的关系不同. 他们之间不同点是维护的关系不同 *多对一维护的关系是:多指向一的关系,有了此关系,加载多的时候可以将一加载上来. *一对多维护的关系是:一指向多的关系,有了此关系,在加载一的时候可以将多加载上来. 一个班级有多个学生,通过班级可以看到学生信息. Class

浅谈Hibernate关系映射(2)

继上篇博客 一对一关系映射:一对一关联映射在实际生活中是比较常见的,如人与身份证的关系,通过人这个对象可以找到他相关的内容. 一对一单向(主键): 单向一对一主键关联,靠的是它们的主键相等,从Person中能看到IdCard,也就是把t_idCard中的主键拿过来当做t_Pseron的主键. 如图的线表示一个关联,在person中可以看见idcard.即在person中持有idCard的引用 person类的映射关系 <hibernate-mapping> <class name=&qu

浅谈Hibernate关系映射(4)

继上篇博客 多对多关联映射(单向) 多对多对象关系映射,需要加入一张新表完成基本映射. Hibernate会自动生成中间表 Hibernate使用many-to-many标签来表示多对多的关联,多对多的关联映射,在实体类中,跟一对多一样,也是用集合来表示的. 如下图所示 通过User可以查看Role的信息 User的映射文件 <hibernate-mapping> <class name="com.bjpowernode.hibernate.User"> <

浅谈Hibernate中映射集合属性以及主键和外键

首先说明一下什么叫主键以及外键. 主键和外键是对于数据库来说的,数据库的表才有主键外键的说法. 主键:主键是指标识某个表中唯一且非空的一条记录行的列,这个列中的值不允许有重复的值,用于确定一个表中的一条记录,实际上主键就是告诉别人:这个数据列是唯一的. 外键:引用另外一个表中的主键,在当前表中不一定为唯一的,但是在被引用表中一般唯一.对于关系型数据库来说(比如MySQL)外键是联系数据表之间的唯一方式,主要目的是控制存储在外键表中的数据. 建立外键的前提:本表的列必须与外键类型相同(外键必须是外

Hibernate关系映射基础

1.  Hibernate关系映射基础 1.1.  Doctype <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 指定根元素和dtd文件的命名空间. 1.2.  hibernate-mapping <hiberna

【SSH快速进阶】——Hibernate继承映射:每个类映射一张表

上文说了每棵继承树映射一张表,本文继续描述让每个类都映射一张表的配置. 场景 与上篇文章场景一样,如下类图 上图中Pig类和Bird类继承Animal类,要让每个类映射一张表,就是让着三个类都分别映射一张表,但同时这三张表也跟对应的三个类似的,有继承关系,如下表所示: (表 1) Pig和Bird的记录都表示一个动物,因此都会在Animal对应的表中存储,而它们各自的拓展属性则存储在各自对应的表中,主键与Animal对应记录的主键各自对应. 配置 PO对象 跟上篇文章一样,实体类没有任何变化.

【SSH快速进阶】——Hibernate继承映射:每棵继承树映射一张表

我们都知道,Hibernate最大的一个优点就是使开发更加"面向对象",类与类之间有继承关系,Hibernate中也对这种继承关系提供了映射的封装. Hibernate为继承映射提供了三种策略 1.每棵继承树使用一张表 2.每个子类使用一张表 3.每个具体类使用一张表 本文对第一种策略进行说明. 场景 如下类图 上图中Pig类和Bird类继承Animal类,每棵继承树对应一张表,即在同一棵继承树中,所有的类的对象信息(记录)共同存放到一张表中,要判断某条记录属于哪个对象,需要在表中添加

【SSH快速进阶】——Hibernate继承映射:每个具体类映射一张表

上篇文章说的是每个类映射一张表,不管是父类还是子类.与上篇文章不同的是,这里是每个"具体类"映射一张表,什么意思呢?就是让每个子类(具体的.有意义的类)映射一张表. 场景 与上篇文章场景一样,如下类图 上图中Pig类和Bird类继承Animal类,要让每个具体类映射一张表,就是只映射Pig和Bird,如下表所示: (表 1) 上面的表有个特点就是,t_pig和t_bird的主键永远都不会相同.因为表面上看起来这是两张表,但实际上存储的都是动物(同一类型),所以还可以看做是一张表. 配置

Java学习笔记-Hibernate关系映射

1. 初识Hibernate——关系映射 http://blog.csdn.net/laner0515/article/details/12905711 2. Hibernate 笔记8 关系映射1(多对一,一对多): http://www.cnblogs.com/zilong882008/archive/2011/11/05/2236559.html 3. Hibernate关联映射 http://www.cnblogs.com/huxi/archive/2009/12/15/1624988.