Hibernate一对多关联映射
来源:互联网 发布:网络装备交易排行榜 编辑:程序博客网 时间:2024/05/19 13:08
上篇总结到多对一的关联映射,这篇总结一对多关联映射。
一对多关联映射和多对一关联映射映射原理是一致的,都是在多的一端加入一个外键,指向一的一端。我们以班级和学生的例子理解。
先看一张UML图:
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) {this.students = students;}}
<?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端:
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;}}
<?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>
使用Junit测试:HibernateUtils类见上篇:
package com.bjpowernode.hibernate;import java.util.HashSet;import java.util.Iterator;import java.util.Set;import org.hibernate.Session;import junit.framework.TestCase;public class One2ManyTest extends TestCase {public void testSave1() {Session session = null;try {session = HibernateUtils.getSession();session.beginTransaction();Student student1 = new Student();student1.setName("张三");Student student2 = new Student();student2.setName("李四");Classes classes = new Classes();classes.setName("动力节点");Set students = new HashSet();students.add(student1);students.add(student2);classes.setStudents(students);//抛出TransientObjectException//因为Student不是Persistent状态的对象,它是Transient状态的对象session.save(classes);session.getTransaction().commit();}catch(Exception e) {e.printStackTrace();session.getTransaction().rollback();}finally {HibernateUtils.closeSession(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);}}public void testLoad1() {Session session = null;try {session = HibernateUtils.getSession();session.beginTransaction();Classes classes = (Classes)session.load(Classes.class, 1);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);}}}
从测试中我们可以看到,多对一和一对多的区别:
* 多对一维护的关系是:多指向一的关系,有了此关系,在加载多的时候可以将一加载上来
* 一对多维护的关系是:一指向多的关系,有了此关系,在加载一的时候可以将多加载上来
但是一对多有缺陷:
* 因为多的一端Student不知道Classes的存在(也就是Student没有维护与Classes的关系)所以在保存Student的时候关系字段classesid是为null的,如果将该关系字段设置为非空,则将无法保存数据
* 另外因为Student不维护关系,而Classes维护关系,Classes就会发出多余的update语句,保证Classes和Student有关系,这样加载Classes的时候才可以把该Classes对应的学生加载上来
为了解决这个问题。我们通常采用一对多双向关联映射。双向关联比一对多单向关联的代码和配置不同在于:
Classes端一样,Student端多了Classes的引用。
package com.bjpowernode.hibernate;public class Student {private int id;private String name;private 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;}public Classes getClasses() {return classes;}public void setClasses(Classes classes) {this.classes = classes;}}Classes端的配置文件中多了inverse属性
<set name="students" inverse="true"> <key column="classesid"/><one-to-many class="com.bjpowernode.hibernate.Student"/></set>
Student端的配置文件中多了many-to-one标签
<many-to-one name="classes" column="classesid"/>
!!!注意:<key>标签和<many-to-one>标签加入的字段保持一直,否则会产生数据混乱
知识补充:inverse和cascade
* inverse属性可以用在一对多和多对多双向关联上,inverse属性默认为false,为false表示本端可以维护关系,如果inverse为true,则本端不能维护关系,会交给另一端维护关系,本端失效。所以一对多关联映射我们通常在多的一端维护关系,让一的一端失效,所以设置为inverse为true
* inverse是控制方向上的反转,只影响存储, cascade是操作上的连锁反映
总结:一对多关联映射和多对一关联映射映射原理是一致的,都是在多的一端加入一个外键,指向一的一端。
- Hibernate一对多关联映射
- hibernate---->一对多关联映射
- Hibernate一对多关联映射
- hibernate关联映射(一对多)
- hibernate---一对多关联映射
- 【Hibernate】一对多关联映射
- 【Hibernate】一对多关联映射
- Hibernate关联映射--一对多
- Hibernate一对多关联映射
- Hibernate关联映射--一对多映射
- Hibernate一对多单向关联映射
- Hibernate一对多关联双向映射
- Hibernate映射一对多单向关联(之一)
- Hibernate一对多关联映射—单向
- Hibernate 映射一对多关联关系
- hibernate一对多关联映射—单向
- hibernate一对多关系映射(自身关联)
- hibernate 一对多 关系关联映射
- 漫谈自动化测试(三)——建设阶段划分
- x-requested-with
- iOS编程规范
- windows下为vim配置Taglist、Ctags
- iOS媒体视频播放器应用源码
- Hibernate一对多关联映射
- 最长共同子序列 --- DP(动态规划)
- Count and Say @python 题解
- Java中创建(实例化)对象的五种方式
- 解析XML文件的几种方式及其比较
- suse11如何配置rsh
- [boost][2015-04-23] boost linux下的安装 编译 使用
- decorators.xml学习
- 你真的了解:IIS连接数、IIS并发连接数、IIS最大并发工作线程数、应用程序池的队列长度、应用程序池的...