【SSH系列】Hibernate映射 -- 一对多关联映射
映射原理
一对多关联映射和多对一关联映射的映射原理是一样一样的,所以说嘛,知识都是相通的,一通百通,为什么说一对多关联映射和多对一关联映射是一样的呢?因为她们都是在多的一端加入一个外键,指向一的一段,关联关系都是在多的一端进行维护,只是我们在写映射的时候发生了变化。
一对多和多对一的映射原理是一样的,但是她们之间也存在着小小的区别,毕竟世界上没有两片完全相同的叶子,她们之间的区别就是维护的关系不同,我们先来看多对一,多端维护一端的关系,在加载多端的时候,可以将一端加载上来;一对多,一端维护多端的关系,在加载一端的时候,可以将多端加载上来。一对多关联映射也存在两种策略,单向和双向,今天这篇博文,小编就来简单的介绍一下一对多关联映射,希望对有需要的小伙伴有帮助,不足之处,还请小伙伴们多多指教`(*∩_∩*)′。
一对多单向关联映射
我们都知道,一个班级是由多个学生组成的,ok,今天的故事就从班级和学生开始拉开帷幕,我们依然从uml入手,首先我们来看对象模型,如下图所示:
从对象模型中,我们可以看出,Classes持有Student的一个引用,由于是单向关联,所以数据在加载Classes的时候,会把Student加载上来,但是Student并不知道Classes的存在。接着,我们开始来编写代码的部分。
第一步、编写实体Classes && Student,代码如下所示,首先我们来编写Classes,代码如下所示:
package com.bjpowernode.hibernate;
import java.util.Set;
public class Classes {
private int id;
private String name;
private Set Students;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set getStudents() {
return Students;
}
public void setStudents(Set students) {
Students = students;
}
Student的代码如下所示:
package com.bjpowernode.hibernate;
public class Student {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
第二步、编写映射文件,首先编写Classes.hbm.xml代码如下所示:
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="com.bjpowernode.hibernate.Classes" table="t_classes"> <id name="id"> <generator class="native"/> </id> <property name="name"/> <set name = "students"> <key column="classesid"/> <one-to-many class="com.bjpowernode.hibernate.Student"/> </set> </class> </hibernate-mapping>
接着编写Student.hbm.xml的代码,如下所示:
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name ="com.bjpowernode.hibernate.Student" table="t_student"> <id name="id"> <generator class="native"/> </id> <property name="name"/> </class> </hibernate-mapping>
第三步、编写hibernate.cfg.xml的代码,建立数据库并且添加相应的映射,代码如下所示:
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory > <!-- MySql数据库驱动 --> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <!-- 数据库名称 --> <property name="hibernate.connection.url"> jdbc:mysql:///hibernate_one2many_1</property> <!-- 数据库的用户名 --> <property name="hibernate.connection.username">root</property> <!-- 数据库的密码 --> <property name="hibernate.connection.password">123456</property> <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <!-- 显示语句 --> <property name="hibernate.show_sql">true</property> <!-- 格式排版 --> <!-- <property name="hibernate.format_sql">true</property> --> <mapping resource="com/bjpowernode/hibernate/Student.hbm.xml"/> <mapping resource="com/bjpowernode/hibernate/Classes.hbm.xml"/> </session-factory> </hibernate-configuration>
接着创建数据库,并且运行ExportDB,生成相应的表结构如下所示:
接着,我们向表里面插入数据,代码如下所示:
package com.bjpowernode.hibernate;
import java.util.HashSet;
import java.util.Set;
import junit.framework.TestCase;
import org.hibernate.Session;
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);
//可以成功保存数据
//但是会发出多余的update语句来维持关系
session.save(classes);
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
运行代码效果如下所示:
从上面的demo实例我们可以看出来,因为多端Student不知道Classes的存在,也就是Student不维护与Classes的关系,所以在保存Student的时候,字段classesid为空,如果该字段设置为非空,则将无法保存数据;因为Student不维护关系,而Classes维护关系,Classes将会发出多余的update语句。介绍完了一对多单向关联映射,接着我们来一起学习一下一对多双向关联映射,对象模型如下所示:
双向关联映射
双向关联映射对比单向关联映射,对象的加载方向由单向变成了双向。我们依然以为Classes和Student为例进行讲解。
第一步、编写实体Classes && Student,代码如下所示,首先我们来编写Classes,代码如下所示:
package com.bjpowernode.hibernate;
import java.util.Set;
public class Classes {
private int id;
private String name;
private Set Students;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set getStudents() {
return Students;
}
public void setStudents(Set students) {
Students = students;
}
}
接着,编写Student的代码,如下所示:
package com.bjpowernode.hibernate;
public class Student {
private int id;
private String name;
private Classes classes;
public Classes getClasses() {
return classes;
}
public void setClasses(Classes classes) {
this.classes = classes;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
第二步、编写映射文件,首先编写Classes.hbm.xml代码如下所示:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.bjpowernode.hibernate.Classes" table="t_classes">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<set name = "students">
<key column="classesid"/>
<one-to-many class="com.bjpowernode.hibernate.Student"/>
</set>
</class>
接着编写Student.hbm.xml的代码,如下所示:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name ="com.bjpowernode.hibernate.Student" table="t_student">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<many-to-one name="classes" column="classesid"/>
</class>
</hibernate-mapping>
第三步、编写hibernate.cfg.xml的代码,建立数据库并且添加相应的映射,代码如下所示:
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory >
<!-- MySql数据库驱动 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<!-- 数据库名称 -->
<property name="hibernate.connection.url"> jdbc:mysql:///hibernate_one2many_2</property>
<!-- 数据库的用户名 -->
<property name="hibernate.connection.username">root</property>
<!-- 数据库的密码 -->
<property name="hibernate.connection.password">123456</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 显示语句 -->
<property name="hibernate.show_sql">true</property>
<!-- 格式排版 -->
<!-- <property name="hibernate.format_sql">true</property> -->
<mapping resource="com/bjpowernode/hibernate/Student.hbm.xml"/>
<mapping resource="com/bjpowernode/hibernate/Classes.hbm.xml"/>
</session-factory>
</hibernate-configuration>
接着创建数据库,并且运行ExportDB,生成相应的表结构如下所示:
接着,我们向表里面插入数据,代码如下所示:
package com.bjpowernode.hibernate;
import java.util.HashSet;
import java.util.Set;
import junit.framework.TestCase;
import org.hibernate.Session;
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);
//可以成功保存数据
//但是会发出多余的update语句来维持关系
session.save(classes);
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
运行代码,效果如下所示:
小编寄语:为什么多对一关联映射不存在单向一对多中的问题呢?在多对一关联映射里面,由于关系是在多的一端进行维护的,加载的时候从多的一端进行加载,当然没有问题。总结一下:在多对一关联映射中,如果用到,经常采用双向的方式来完成映射,弥补单向加载时的问题。ok,今天的hibernate一对多映射就介绍到这里,还请小伙伴们多多指教,在下一篇博文中,小编将继续介绍hibernate映射的相关知识,敬请期待……
【SSH系列】Hibernate映射 -- 一对多关联映射的更多相关文章
- 【SSH进阶之路】Hibernate映射——一对多关联映射(七)
上上篇博文[SSH进阶之路]Hibernate映射——一对一单向关联映射(五),我们介绍了一对一的单向关联映射,单向是指只能从人(Person)这端加载身份证端(IdCard),但是反过来,不能从身份 ...
- (Hibernate进阶)Hibernate映射——一对多关联映射(七)
一对多关联映射 映射原理 一对多关联映射和多对一关联映射的映射原理是一致的,都是在多的一端加入一个外键,指向一的一端.关联关系都是由多端维护,只是在写映射时发生了变化. 多对一和一对多的区别 多对一和 ...
- 【SSH进阶之路】Hibernate映射——多对多关联映射(八)
上篇博文[SSH进阶之路]Hibernate映射——一对多关联映射(七),我们介绍了一对多关联映射,它是多对多关联映射的基础. 多对多映射是现实生活中最常见的映射,也是最容易理解的映射.废话少说,直接 ...
- hihernate一对多关联映射
hihernate一对多关联映射 一对多关联映射利用了多对一关联映射原理 多对一关联映射:在多的一端加入一个外键指向一的一端,它维护的关系是多指向一 一对多关联映射:在多的一端加入一个外键指向一的一端 ...
- 【SSH系列】Hibernate映射 -- 多对多关联映射
映射原理 在数据库学习阶段,我们知道,如果实体和实体之间的关系是多对多,那么我们就抽出来第三张表,第一张表和第二张表的主键作为第三表的联合主键,结合我们的hibernate,多对多关联,无论 ...
- 【SSH系列】hibernate映射 -- 一对一双向关联映射
开篇前言 上篇博文[SSH进阶之路]hibernate映射--一对一单向关联映射,小编介绍了一对一的单向关联映射,单向是指只能从人(Person)这端加载身份证端(IdCard),但是反过来,不能从身 ...
- 【SSH系列】Hibernate映射 -- 一对一单向关联映射
映射原理 一对一关联映射:两个实体对象之间是一对一的关联映射,即一个对象只能与另外唯一的一个对象相对应.有两种策略可以实现一对一的关联映射: a.主键关联:即让两个对象具有相 ...
- 【SSH进阶之路】Hibernate映射——一对一双向关联映射(六)
上篇博文[SSH进阶之路]Hibernate映射--一对一单向关联映射(五),我们介绍了一对一的单向关联映射,单向是指仅仅能从人(Person)这端载入身份证端(IdCard),可是反过来.不能从身份 ...
- 【SSH进阶之路】Hibernate映射——一对一单向关联映射(五)
[SSH进阶之路]Hibernate基本原理(一) ,小编介绍了Hibernate的基本原理以及它的核心,採用对象化的思维操作关系型数据库. [SSH进阶之路]Hibernate搭建开发环境+简单实例 ...
随机推荐
- NGUI----简单聊天系统一
1:聊天背景的创建 新建一个场景-----保存场景 NGUI---->Create-----Panel 选中UIRoot,然后新建一个sprite 选择图集 效果如下图 添加一个可拖拽的功能 选 ...
- a标签点击页面刷新但还保存当前点击的class是激活的状态
$(".shop-list1").find("li").each(function(){ var href=$(this).attr(&q ...
- 关于Java中的Null
什么是Java中的Null? null在Java中是一个非常重要的概念,它最初是为了表示缺少某些东西,例如缺少用户.资源或任何东西而发明出来的.但是这也为Java程序员带来了很多麻烦,比如最常见的空指 ...
- Java面试题—初级(7)
作为一枚Java后端开发者,数据库知识必不可少,对数据库的掌握熟悉度的考察也是对这个人是否有扎实基本功的考察.特别对于初级开发者,面试可能不会去问框架相关知识,但是绝对不会不去考察数据库知识,这里收集 ...
- pat 1001 A+B Format
题目链接:传送门 题目简述: 1. 给定两个整数值a,b: 2.范围-1000000 <= a, b <= 1000000: 3.按指定格式输出结果 例:-100000 9 输出: -99 ...
- 半径无关快速高斯模糊实现(附完整C代码)
之前,俺也发过不少快速高斯模糊算法. 俺一般认为,只要处理一千六百万像素彩色图片,在2.2GHz的CPU上单核单线程超过1秒的算法,都是不快的. 之前发的几个算法,在俺2.2GHz的CPU上耗时都会超 ...
- NKOJ4191 Trie树
问题描述 字母(Trie)树是一个表示一个字符串集合中所有字符串的前缀的数据结构,其有如下特征: 1.树的每一条边表示字母表中的一个字母 2.树根表示一个空的前缀 3.树上所有其他的节点都表示一个 ...
- BZOJ4894 天赋
Description 小明有许多潜在的天赋,他希望学习这些天赋来变得更强.正如许多游戏中一样,小明也有n种潜在的天赋,但有 一些天赋必须是要有前置天赋才能够学习得到的.也就是说,有一些天赋必须是要在 ...
- bzoj 3451 Normal
Description 某天WJMZBMR学习了一个神奇的算法:树的点分治! 这个算法的核心是这样的: 消耗时间=0 Solve(树 a) 消耗时间 += a 的 大小 如果 a 中 只有 1 个点 ...
- 51nod 1752 哈希统计
Description Solution 考虑用倍增来处理答案: 设 \(f[i][j]\) 表示长度恰好为 \(2^{i}\) 的哈希值为 \(j\) 的字符串的种数 \(dp[i][j]\) 表示 ...