“一对多”,顾名思义,是由“一”的一端加载“多”的一端,关系交由“一”来维护。反映在Java代码中就是在“一”的一端中持有“多”一端的集合,而hibernate把这种关系反映到数据库的策略是在“多”一端的表上加上一个外键指向“一”一端表。显现,其实这采用的还是“多対一”的映射原理。
但是,在“一”一端维护关系是我们不提倡的,因为它有不可避免的缺点,即级联插入数据的时候要先插“多”一端,这样造成了两方面的不妥:1.如果我们把“多”一端的外键必须添加非空约束,将导致数据不能插入;2.即使外键不设置为非空,在插入“多”一端数据时外键将暂时为空( 因为此时它所引用的“一”记录还没有插入),而只有等到它所引用的“一”记录插入后,再发出update语句修改外键,这样的效率必然降低。
不管怎样,还是来看看我的Classes和Student怎么做的吧。
1.实体模型:
2.关系模型:
3.实体类:
Student.java
public class Student {
private Integer id;
private String name;
//一系列的setter.getter方法
@Override
public String toString() {
return "name of student: " + name;
}
}
private Integer id;
private String name;
//一系列的setter.getter方法
@Override
public String toString() {
return "name of student: " + name;
}
}
Classes.java
public class Classes {
private Integer id;
private String name;
private Set<Student> students;
//一系列的setter.getter方法
@Override
public String toString() {
return "name of class: " + name;
}
}
private Integer id;
private String name;
private Set<Student> students;
//一系列的setter.getter方法
@Override
public String toString() {
return "name of class: " + name;
}
}
4.映射文件:
Student.hbm.xml
<class name="com.sxt.hibernate.one2many.entity.Student" table="sxt_hibernate_student">
<id name="id" length="4">
<generator class="native"></generator>
</id>
<property name="name" length="10"></property>
</class>
<id name="id" length="4">
<generator class="native"></generator>
</id>
<property name="name" length="10"></property>
</class>
Classes.hbm.xml
<class name="com.sxt.hibernate.one2many.entity.Classes" table="sxt_hibernate_class">
<id name="id" length="4">
<generator class="native"></generator>
</id>
<property name="name" length="10"></property>
<!-- 配置集合属性 -->
<set name="students" cascade="save-update">
<!-- key的含义,指在另一端增加的外键指向本主键.
如果设置上属性not-null="true",表示该外键非空,则在由"一"的一端维护关系时,
可能导致插入数据异常PropertyValueException.
-->
<key column="class_id"></key>
<!--one-to-many含义,指出set集合中的元素类型,以供加载时使用 -->
<one-to-many class="com.sxt.hibernate.one2many.entity.Student"/>
</set>
</class>
<id name="id" length="4">
<generator class="native"></generator>
</id>
<property name="name" length="10"></property>
<!-- 配置集合属性 -->
<set name="students" cascade="save-update">
<!-- key的含义,指在另一端增加的外键指向本主键.
如果设置上属性not-null="true",表示该外键非空,则在由"一"的一端维护关系时,
可能导致插入数据异常PropertyValueException.
-->
<key column="class_id"></key>
<!--one-to-many含义,指出set集合中的元素类型,以供加载时使用 -->
<one-to-many class="com.sxt.hibernate.one2many.entity.Student"/>
</set>
</class>
5.hibernate配置文件:
参考前面的。
6.测试方法:
public static void main(String[] args) {
Session session = HibernateUtils.getSession();
Transaction t = session.beginTransaction();
try {
/**
* 测试插入数据
*/
/*
* Student student1=new Student();
* student1.setName("奇隆");
*
* Student student2=new Student();
* student2.setName("有朋");
*
* Set<Student> students=new HashSet<Student>();
* students.add(student1);
* students.add(student2);
*
* Classes classes=new Classes();
* classes.setName("不一班");
* classes.setStudents(students);
* //存储不成功.报错:org.hibernate.TransientObjectException
* //因为此时student对象还没有持久化,classes引用了瞬时对象student1,student2
* session.save(classes);
*/
Student student1=new Student(); student1.setName("奇隆");
//session.save(student1);//先把student对象持久化
Student student2=new Student();
student2.setName("有朋");
//session.save(student2);
Set<Student> students=new HashSet<Student>();
students.add(student1);
students.add(student2);
Classes classes=new Classes();
classes.setName("不一班");
classes.setStudents(students);
//存储成功.sql语句如下:
/*
Hibernate: insert into sxt_hibernate_class (name, id) values (?, ?)
Hibernate: insert into sxt_hibernate_student (name, id) values (?, ?)
Hibernate: insert into sxt_hibernate_student (name, id) values (?, ?)
Hibernate: update sxt_hibernate_student set class_id=? where id=?
Hibernate: update sxt_hibernate_student set class_id=? where id=? */
//可见在存储class之后,发出两个update语句,把它的两个student对象的class_id更新了.
//这是因为关系由"一"的一端维护(即class维护关系).这显然会降低效率.
//所以对于一对多,我们一般把关系交给"多"的一端维护.
session.save(classes);
/**
* 测试加载数据
*/
/* Classes classes = (Classes) session.load(Classes.class, 3);
System.out.println(classes);
Set<Student> students = classes.getStudents();
for (Iterator<Student> stus = students.iterator(); stus.hasNext();) {
System.out.println(stus.next());
}*/
t.commit();
} catch (HibernateException e) {
e.printStackTrace();
t.rollback();
} finally {
HibernateUtils.closeSession(session);
}
}
}
Session session = HibernateUtils.getSession();
Transaction t = session.beginTransaction();
try {
/**
* 测试插入数据
*/
/*
* Student student1=new Student();
* student1.setName("奇隆");
*
* Student student2=new Student();
* student2.setName("有朋");
*
* Set<Student> students=new HashSet<Student>();
* students.add(student1);
* students.add(student2);
*
* Classes classes=new Classes();
* classes.setName("不一班");
* classes.setStudents(students);
* //存储不成功.报错:org.hibernate.TransientObjectException
* //因为此时student对象还没有持久化,classes引用了瞬时对象student1,student2
* session.save(classes);
*/
Student student1=new Student(); student1.setName("奇隆");
//session.save(student1);//先把student对象持久化
Student student2=new Student();
student2.setName("有朋");
//session.save(student2);
Set<Student> students=new HashSet<Student>();
students.add(student1);
students.add(student2);
Classes classes=new Classes();
classes.setName("不一班");
classes.setStudents(students);
//存储成功.sql语句如下:
/*
Hibernate: insert into sxt_hibernate_class (name, id) values (?, ?)
Hibernate: insert into sxt_hibernate_student (name, id) values (?, ?)
Hibernate: insert into sxt_hibernate_student (name, id) values (?, ?)
Hibernate: update sxt_hibernate_student set class_id=? where id=?
Hibernate: update sxt_hibernate_student set class_id=? where id=? */
//可见在存储class之后,发出两个update语句,把它的两个student对象的class_id更新了.
//这是因为关系由"一"的一端维护(即class维护关系).这显然会降低效率.
//所以对于一对多,我们一般把关系交给"多"的一端维护.
session.save(classes);
/**
* 测试加载数据
*/
/* Classes classes = (Classes) session.load(Classes.class, 3);
System.out.println(classes);
Set<Student> students = classes.getStudents();
for (Iterator<Student> stus = students.iterator(); stus.hasNext();) {
System.out.println(stus.next());
}*/
t.commit();
} catch (HibernateException e) {
e.printStackTrace();
t.rollback();
} finally {
HibernateUtils.closeSession(session);
}
}
}
本文出自 “夜狼” 博客,请务必保留此出处http://yangfei520.blog.51cto.com/1041581/275656
相关推荐
这篇博客文章“hibernate一对多关联映射(单向关联)”将深入讲解如何配置和使用这种映射关系。 在单向关联中,只有一个实体知道另一个实体的存在,也就是说,只有父实体("一"的一端)有对子实体("多"的一端)的...
在Java的持久化框架Hibernate中,单向一对多关联映射是常见的数据关系处理方式,尤其是在处理数据库中的实体类和表之间的关系时。本主题主要关注如何使用注解来实现这种映射。Hibernate通过注解使得对象关系映射...
本练习主要关注的是Hibernate中的单向多对多关联映射,这是一种常见的关系数据库设计模式,用于表示两个实体间复杂的关系。 在多对多关联中,两个实体类可以相互拥有多个实例,但只在一个方向上建立关联。例如,...
包含《多对多双向关联映射》《多对一单向关联映射》《多对一双向关联映射》《一对多单向关联映射》等文档,并有图解及例子,非常适合新手学习,尤其是刚刚接触hibernate,对映射关系不清楚的。。。。
在关系数据库中,一对多关联意味着一个表中的记录可以对应另一个表中的多个记录。例如,一个班级可以有多个学生,而每个学生只属于一个班级。在Hibernate中,我们可以通过配置XML映射文件或使用注解来实现这种关联。...
在Hibernate中,一对一关联映射分为单向和双向。单向一对一映射通常涉及一个实体持有另一个实体的引用,而双向一对一映射则意味着两个实体都可以互相引用。这种关联关系在数据库层面通常通过主键外键约束来实现,但...
在Java的持久化框架Hibernate中,多对多关联映射是一种常见的关系模型,它用于处理两个实体类之间存在多个对应关系的情况。这篇博客"hibernate多对多关联映射(单项关联)"深入探讨了如何在Hibernate中实现这种映射...
在本主题"Hibernate单向一对多关联映射(XML版)"中,我们将深入探讨如何使用XML配置来实现数据库中一个实体类对应多个实体类的关联关系。 在Hibernate中,一对多关联是一种常见的关系映射类型,它反映了数据库中的...
总结,Hibernate的一对多关联映射提供了处理实体间多对一关系的能力,既可实现单向关联,也可实现双向关联。通过合理配置,可以优化数据加载策略,进行级联操作,并方便地进行数据的保存和查询。在实际开发中,理解...
在本教程中,我们将探讨如何实现一对一唯一外键关联映射,特别关注单向关联的情况。 ### 1. Hibernate一对一关联概述 一对一关联分为两种类型:共享主键关联(Primary Key Join)和唯一外键关联(Unique Foreign ...
在一对多关联映射中,还有单向关联和双向关联之分。单向关联是指一端维护多端的关系,而多端不知道一端的存在。双向关联是指一端维护多端的关系,而多端也维护一端的关系。 在本文中,我们通过一个简单的示例来演示...
Hibernate 一对一唯一外键关联映射详解 Hibernate是一种流行的Java持久层框架,提供了多种关联映射方式,其中一对一唯一外键关联映射是一种常见的关联方式。在本文中,我们将详细介绍Hibernate一对一唯一外键关联...
1. **一对多关联**:例如,一个公司有多个员工,可以创建一个Company类(对应数据库表Company)和一个Employee类(对应Employee表)。Company类包含一个Employee列表,表示一个公司可以拥有多个员工。 2. **多对一...
本篇将详细探讨"一对多单向和双向映射"这一主题,结合标签中的"源码"和"工具",我们将深入理解这些概念,并可能涉及到具体的代码实现。 首先,映射是ORM框架的核心,它允许开发者将数据库表与Java类之间的关系进行...
#### 一对多关联映射单向(one-to-many) - **对象模型**:定义了一个实体类与其多个子实体类之间的关系。 - **Classes实体类**:表示班级信息。 - **Students实体类**:表示学生信息。 - **Student映射文件**:...
在Java的持久化框架Hibernate中,多对一(ManyToOne)关联关系是一种常见的对象关系映射(ORM)场景。这种关系通常出现在一个实体类拥有多条与另一个实体类相关的记录,而另一个实体类可能只有一条对应的记录。例如...
本教程主要聚焦于Hibernate中的一个关键概念——关系映射,特别是多对一单向关联的实现。这种关联类型常出现在数据库设计中,比如一个部门可以有多名员工,但一个员工只属于一个部门。 首先,我们要理解多对一关系...