上篇文章讨论了双向关联的一对一映射,用了两个章节,主要是从主键和外键两种关联映射展开具体讨论。双向关联的映射须要在两个映射文件里分别加入相互的相应关系。斌刚在相应的类中加入相应的关联类的属性。这样在一端载入时才干载入到还有一端的对象。关联中经常使用的主要有多对一、一对一、一对多和多对多。我们已经讨论了两种映射关系。接下来将会讨论一对多的关系。

一、单向一对多


        前篇文章中以前对多对一的关系展开了讨论,当中主要使用的是<many-to-one>的关系,在多的一端维护一的一端,那和今天要讨论的一对多的关系它们之间是否有关联呢?在关系和对象模型中存在了一对多关系所以理所当然就会有多对一的关系,Hibernate相同提供了一对多关系的标签<one-to-many>。

        一对多关系的对象模型在日常生活中也常常看到,就拿学生和班级来说。一个班级里有多个学生。所以班级和学生的关系是一对多的关系,映射到对象模型中。例如以下图:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemhhbmdfeGlueGl1/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

       对象模型说明了这样的一对多的关系是由一的一端来维护的,那么映射成关系模型就是一个班级字段以下会有多个学生,这样就形成了一对多的关系,通过班级可以查询获得学生信息,相应的关系模型例如以下图:


1、基本配置


       有了对象模型接下来就让它们映射为相应的关系代码。在进行关系映射时须要在一的一端加入<one-to-many>标签。另外还须要在一的一端加入Set属性,它支持延迟载入,然后在映射文件加入set标签。并指明一对多的关系,这样就行在一的一端查询获取多的一端。

    Classes类及映射文件
      它是模型中最重要的一端,在该端须要加入相应的set属性。并在配置文件里加入set标签,在set标签中配置相应的<one-to-many>对象,详细Classes.java对象代码例如以下:
<pre name="code" class="java">package com.src.hibernate;

import java.util.Set;

public class Classes {
private int id;
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;
}
private String name; //Set支持延迟载入
private Set students;
public Set getStudents() {
return students;
}
public void setStudents(Set students) {
this.students = students;
}
}

Classes对象中使用了set属性。可是仅仅是说明了延迟载入的属性,并没有为属性配置相应的对象。属性的对象是要在映射文件里来配置的。须要加入set标签,并在set标签中加入<one-to-many>标签,详细例如以下代码:

<?

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.hibernate.Classes" table="t_classes">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<set name="students">
<key column="classesid"></key>
<one-to-many class="com.hibernate.Student"></one-to-many>
</set>
</class>
</hibernate-mapping>

相应的Student对象中的代码和映射文件不须要什么特殊的配置,仅仅须要依照通常的写法编写就可以,详细的配置方法不再详述,非常easy。

配置好后须要生成相应的SQL语句。将对象模型转化为关系模型时Hibernate生成相应的语句例如以下:

alter table t_student drop foreign key FK4B9075705E0AFEFE
drop table if exists t_classes
drop table if exists t_student
create table t_classes (id integer not null auto_increment, name varchar(255), primary key (id))
create table t_student (id integer not null auto_increment, name varchar(255), classesid integer, primary key (id))
alter table t_student add index FK4B9075705E0AFEFE (classesid), add constraint FK4B9075705E0AFEFE foreign key (classesid) references t_classes (id)

生成的相应的关系模型例如以下图:


 对照SQL语句和关系模型。对应的表之间的关联是通过外键来维护的,首先是创建两张表,并指定表的主键,最后加入一对多的外键关联关系。

2、基本操作

       在对数据库的操作无非是读和写两种。改动也属于写的一种,接下来看看是怎样向数据库中写入和读取操作的。

       写入数据
       写入数据须要注意的是一对多的关系,所以在加入的时候须要加入多个学生类,另外因为在classes中加入了相应的set属性,所以在加入Student对象时应该使用HashSet来加入,这样既可实现一对多的关系,详细例如以下代码:
public void testSave2(){
Session session=null;
try{
session=HibernateUtils.getSession();
session.beginTransaction(); Student student1=new Student();
student1.setName("zhangsan");
session.save(student1); Student student2=new Student();
student2.setName("lisi");
session.save(student2); Classes classes=new Classes();
classes.setName("ClassOne"); 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);
}
}

那么执行上面的測试用例生成的相应的数据写入到数据库中后例如以下图:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemhhbmdfeGlueGl1/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">


       读取数据
       写入操作相对简单,仅仅须要把全部载入的对象都加入到Transient状态下。执行相应的方法就能够插入内容。可是相应的读取操作就会略微复杂点,由于须要迭代获取全部的学生对象,所以这样的一对多的关系效率并不非常高。详细代码例如以下:
package com.test.hibernate;

import java.util.Iterator;
import java.util.Set;
import com.src.hibernate.*;
import junit.framework.TestCase;
import org.hibernate.Session; public class One2ManyTest extends TestCase {
public void testLoad1(){
Session session=null;
try{
session=HibernateUtils.getSession();
session.beginTransaction(); //获取主键为5的班级信息
Classes classes=(Classes)session.load(Classes.class,5);
//打印班级信息
System.out.println("classes.name="+classes.getName());
//设置学生集合,通过班级载入学生集合
Set students=classes.getStudents();
//迭代集合。打印集合中学生的信息
for(Iterator iter=students.iterator();iter.hasNext();){
Student student=(Student)iter.next(); System.out.println("student.name="+student.getName());
} session.getTransaction().commit();
}catch(Exception e){
e.printStackTrace();
session.getTransaction().rollback();
}finally{
HibernateUtils.closeSession(session);
}
}
}

生成的对应的语句及信息例如以下语句:

Hibernate: select classes0_.id as id1_0_, classes0_.name as name1_0_ from t_classes classes0_ where classes0_.id=?

classes.name=ClassOne
Hibernate: select students0_.classesid as classesid1_, students0_.id as id1_, students0_.id as id0_0_, students0_.name as name0_0_ from t_student students0_ where students0_.classesid=? student.name=lisi
student.name=zhangsan

结语


        一对多的关系也是经经常使用到的,可是这样的关系在载入时效率会不高。由于须要维护的数据较多,所以不建议使用一对多的关系,能够考虑多对一的关系。这样在载入时事实上是一种一对一的关系,载入的效率较高,关系和对象模型得到了优化。这里仅仅是讨论了单向的一对多,下篇文章讨论双向的关联关系。

【Hibernate步步为营】--(一对多映射)之单向关联的更多相关文章

  1. hibernate一对一外键单向关联

    关联是类(类的实例)之间的关系,表示有意义和值得关注的连接. 本系列将介绍Hibernate中主要的几种关联映射 Hibernate一对一主键单向关联Hibernate一对一主键双向关联Hiberna ...

  2. hibernate一对一主键单向关联

    关联是类(类的实例)之间的关系,表示有意义和值得关注的连接. 本系列将介绍Hibernate中主要的几种关联映射 Hibernate一对一主键单向关联Hibernate一对一主键双向关联Hiberna ...

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

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

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

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

  5. hibernate之多对一单向关联

    一个工作组(Group)里能够有多个用户(User),一个User仅仅属于一个Group,这是典型的多对一的关系. 在多对一的关系中正确的数据库设计是在多的这方(在这里是User这方)加一个Group ...

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

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

  7. hibernate多对一单向关联

    关联是类(类的实例)之间的关系,表示有意义和值得关注的连接. 本系列将介绍Hibernate中主要的几种关联映射 Hibernate一对一主键单向关联Hibernate一对一主键双向关联Hiberna ...

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

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

  9. hibernate之关于一对一单向,双向关联映射

    [hibernate]之关于一对一单向,双向关联映射 首先我们来看,Hibernate官方对于一对一单向关联的解释: 基于外键关联的单向一对一关联和单向多对一关联差点儿是一样的. 唯一的不同就是单向一 ...

  10. hibernate一对一外键双向关联

    关联是类(类的实例)之间的关系,表示有意义和值得关注的连接. 本系列将介绍Hibernate中主要的几种关联映射 Hibernate一对一主键单向关联Hibernate一对一主键双向关联Hiberna ...

随机推荐

  1. SP10628 COT - Count on a tree 主席树

    Code: #include<cstdio> #include<cstring> #include<algorithm> #include<string> ...

  2. 你可能需要了解下Laravel集合

    前言 集合通过 Illuminate\Support\Collection 进行实例,Laravel的内核大部分的参数传递都用到了集合,但这并不代表集合就是好的.Laravel作为快捷并优雅的开发框架 ...

  3. 2015,鬼王Xun和GGL比赛,带给我们无尽的欢乐

    一如既往的风格,正文之前,先扯蛋~     这篇文章好久就想写了,一直没有动笔,最近在忙于Android和iOS等技术研究,又忙于金融投资等方面的学习和写作.这个周末,把技术进度延缓了点,把很多闲杂的 ...

  4. Camera Calibration 相机标定:原理简介(二)

    2 针孔相机模型 常见的相机标定中,使用的相机多为针孔相机(Pinhole camera),也就是大家熟知的小孔成像理论.将其中涉及的坐标系之间的相互转换抽离出来,即为针孔相机模型的核心. 上图所示的 ...

  5. 洛谷—— P2663 越越的组队

    https://www.luogu.org/problem/show?pid=2663 题目描述 班级要组织一场综合能力竞赛,全班同学(N个,N是偶数)分成两队互相竞争.老师找到了越越并给了越越一张全 ...

  6. 电源管理ACPI、及APM、GNU/Linux系统下的相应命令使用

    /*********************************************************************  * Author  : Samson  * Date   ...

  7. Ubuntu 10.04 右上角网络管理图标消失的解决的方法

           那个显示网络状态的那个图标.叫做:network-manager.假设是有线网络连接的话.是上下两个箭头,假设是无线网络的话.是一个发射信号的形状. sudo gedit /etc/Ne ...

  8. 重写MPAndroidChart显示标记

    MPAndroidChart是实现图表功能的优秀控件, 能够完毕大多数绘制需求. 对于改动第三方库而言, 优秀的架构是继承开发, 而不是把源代码拆分出去. MP在显示标记控件(MarkView)时, ...

  9. LintCode-赋值运算符重载

    实现赋值运算符重载函数.确保: 新的数据可准确地被复制 旧的数据可准确地删除/释放 可进行 A = B = C 赋值 您在真实的面试中是否遇到过这个题? Yes 例子 假设进行 A = B 赋值.则 ...

  10. vs输出窗口,显示build的时间

    https://stackoverflow.com/questions/82128/displaying-build-times-in-visual-studio Tools... Options.. ...