【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搭建开发环境+简单实例 ...
随机推荐
- [LeetCode] Number of Distinct Islands II 不同岛屿的个数之二
Given a non-empty 2D array grid of 0's and 1's, an island is a group of 1's (representing land) conn ...
- Python---老王开枪
class Person(object): """人类""" def __init__(self,name): super(Person,s ...
- 实验吧_简单的sql注入_1、2、3
简单的sql注入1 看着这个简单的界面,一时间没有特别好的思路,先输入一个1',发生了报错 初步猜测这是一个字符型的注入,他将我们输入的语句直接当成sql语句执行了,按题目的意思后面肯定过滤了很多注入 ...
- javascript的基础(2)--数据类型介绍
1. number数据类型 所有的数字都是Number数据类型 利用typeof运算符可以返回当前数据的数据类型 特殊值:NaN not a number 不是一个数字 注意 :小数的计算可能产生丢失 ...
- 计蒜客NOIP2017提高组模拟赛(三)day1
火山喷发 火山喷发对所有附近的生物具有毁灭性的影响.在本题中,我们希望用数值来模拟这一过程. 在环境里有 n 个生物分别具有 A1,A2,⋯,An点生命值,一次火山喷发总计 MM 轮 ...
- Java文件操作(新建,遍历,删除)
//创建文件 private static void createFile(File file){ try { if(!file.exists()){ if(file.getParentFile() ...
- Linux学习之CentOS(一)--CentOS6.5环境搭建
一.前言 作为一个从事运维工作好几年的老运维来说,linux系统怎能不学呢?所以,这几天自己准备学习一下linux操作系统.废话不多说,直奔主题. 要学linux开发,首先得要安装linux系统吧,这 ...
- Ubuntu一些常用的软件安装及配置
软件 安装 Vim echo "y" | sudo apt-get install vim 安装搜狗输入法 这个我在虚拟机里面尝试了好多遍,不断恢复备份然后重试.终于有了这个纯靠命 ...
- angularjs中关于跨域设置白名单
在config中注入$sceDelegateProvider服务使用resourceUrlWhitelist([])方法添加白名单 跨域时将method的属性设置为"jsonp"就 ...
- angular-cli学习笔记 快速创建代码模板
组件: ng g component component/demo 服务: ng g service service/news 然后在app.module.ts里引入 ng g service ser ...