一对多关联映射(单向Classes---àStudent):
t_classes id | name 1 | 尚学堂 |
t_student id | name | classesid 1 | 10 | 1 2 | 祖儿 | 1 |
一对多关联映射例用了多对一关联映射原理
多对一关联映射:在多的一端加入一个外键指向一的一端,他维护的关系是多指向一的
一对多关联映射:在多的一端加入一个外键指向一的一端,他维护的关系是一指向多的关系
也就是说一对多和多对一的映射策略是一样的,只是站的角度不同
<set name="student">属性名
<key column="classesid"></key>在student生成外键名
<one-to-many class="com.hibernate.Student" />要添加的表得类
</set>
先保存学生,后保存班级的效果:先存学生,但是学生表外键字段插入null,然后保存班级,然后更新学生表对应的外键字段。缺点是会发出很多update语句(与set中的数据条数有关),还有如果外键设置为非空情况肯定会保存失败
在一一端维护关系的缺点:
如果将student表的classesid字段设置为非空,则无法保存
因为不是在student这一端维护关系,所以student不知道是哪个班的,所以需要发出多余的update语句来更新关系
双向:
<many-to-one name="classes" column="classesid"></many-to-one>
注意column一定要和one-to-many中的key的column一样,否则会生成新的列
先存班级,再存学生。
为解决上面的问题:
<set name="student" inverse="true">让一的一端失效,让多的一端维护,关系上的翻转,但是关系字段插入为null,所以只能在多得一端:先存classes将classes设置到student,然后存student
<key column="classesid"></key>
<one-to-many class="com.hibernate.Student" />
</set>
在一的方向保存方式:
Classes classes = new Classes();
Student s1 = new Student();
S1.setClasses(classes);
Set students = new HashSet();
Students.add(s1);
Classes.setStudent(students);
Session.save(classes);
配置需要:
<set name="student" inverse="true" cascade=”all”>
<key column="classesid"></key>
<one-to-many class="com.hibernate.Student" />
</set>
不需要保存student
一对多双向关联:
在一一端的集合上采用key在对方表中加入一个外键指向一一端
在多一端采用many-to-one
注意key标签指定的外键字段必须和many-to-one指定的外键字段一致,否则引用字段的错误
如果在一一端维护一对多关联关系,hibernate会发出多余的update语句,所以我们一般在多的一端来维护关联关系
关于inverse属性:
inverse主要用在一对多和多对多双向关联上,inverse可以被设置到集合标签set上,默认inverse为false,所以我们可以从一一端和多一端维护关联关系,如果设置成inverse为true,则我们只能从多一端来维护关联关系
注意:inverse属性,只影响数据的存储,也就是持久化
inverse和cascade
inverse是关联关系的控制方向
cascade是操作上的连锁反应
保存classes会根据inverse保存student,student根据cascade要先保存classes