副标题#e#
在上一篇博客《一口一口吃掉Hibernate(四)——多对一单向关联映射》中,先容了多对一的关联映射,本日就反过来说一下一对多的单向关联映射。
大概有人会对这2篇博客的题目有点夹杂不清,跟日常说的干系有点差异。我们日常说的好比父子干系,伉俪干系都是说的双向干系,而此刻接头的则是单向干系,所以也就有了多对一和一对多的说法。
二者的干系其实很简朴,只是角度差异罢了。好比说学生和班级的干系。假如从学生角度来看,是多对一的干系。而从班级角度来看,则是一对多的干系。说法很简朴,可是在工具和干系的成立却是纷歧样的。
先看一下一对多的类图(貌似许多几何人的聚合干系都画错了):
Hibernate对付一对多的干系的处理惩罚,是通过操纵Class端,间接操纵可能自动操纵Student端。好比添加,我直接添加Class端的数据,多个Student就会被添加自动添加进去。也可以通过这个Class获取到所有对应的学生信息。随着我来设置一下吧:
首先界说实体类【Class】【Student】
package com.bjpowernode.hibernate; import java.util.Set; /** * 班级类 * @author Longxuan * */ public class Class { private int id; private String name; private Set<Student> students; public Set<Student> getStudents() { return students; } public void setStudents(Set<Student> students) { this.students = 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; } } package com.bjpowernode.hibernate; /** * 学生类 *URL:http://www.bianceng.cn/Programming/Java/201410/45831.htm * @author Longxuan * */ 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; } }
#p#副标题#e#
hibernate.cfg.xml设置文件和hibernate.properties设置文件跟上篇博文中的一致,只是数据库名差异罢了。自行修改可能不修改都可。
Hibernate提供了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 package="com.bjpowernode.hibernate"> <class name="Student" table="t_student"> <id name="id"> <generator class="native" /> </id> <property name="name" /> </class> <class name="Class" table="t_class"> <id name="id"> <generator class="native" /> </id> <property name="name" /> <!-- 配置Set,用于关联多个学生 --> <set name="students"> <!-- 在t_student表中建设外键classid,与本表的id对应 --> <key column="classid"></key> <one-to-many class="Student"></one-to-many> </set> </class> </hibernate-mapping>
设置了one-to-many会自动在t_student表中建设外键classid,与t_class的id映射。
测试类【One2ManyTest】:
package com.bjpowernode.hibernate; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import junit.framework.TestCase; import org.hibernate.Session; import org.hibernate.Transaction; public class One2ManyTest extends TestCase { public void testSave2() { Session session = null; try { session = HibernateUtils.getSession(); session.beginTransaction(); Student student1 = new Student(); student1.setName("张三"); //必需先将student1转化为Persistent状态,不然会抛TransientObjectException //URL:http://www.bianceng.cn/Programming/Java/201410/45831.htm session.save(student1); Student student2 = new Student(); student2.setName("李四"); //必需先将student1转化为Persistent状态,不然会抛TransientObjectException session.save(student2); Class classes = new Class(); classes.setName("提高班"); Set<Student> students = new HashSet<Student> (); students.add(student1); students.add(student2); classes.setStudents(students); //可以乐成生存数据。 //先添加数据,将干系字段配置为null,再用update语句来更新干系字段 //可是会发出多余的update语句来维持干系。 session.save(classes); session.getTransaction().commit(); }catch(Exception e) { e.printStackTrace(); session.getTransaction().rollback(); }finally { HibernateUtils.closeSession(session); } }
功效图:
执行测试前:
,执行测试后:
通过上面的例子,我们可以看出,其实一对多关联映射和多对一关联映射映射道理是一致的,都是在多的一端插手一个外键,指向一的一端。
它们的区别在于维护的干系差异:
多对一维护的干系是:多指向一的干系,有了此干系,在加载多的时候可以将一加载上来
一对多维护的干系是:一指向多的干系,有了此干系,在加载一的时候可以将多加载上来
在一的一端维护干系存在缺陷:
#p#分页标题#e#
因为多的一端Student不知道Class的存在(也就是Student没有维护与Class的干系)所以在生存Student的时候干系字段classid是为null的,假如将该干系字段配置为非空,则将无法生存数据
别的因为Student不维护干系,而Class维护干系,Class就会发出多余的update语句,担保Class和Student有干系,这样加载Class的时候才可以把该Class对应的学生加载上来