Hibernate映射
①多对一映射
事例为studeng-class表关联
学习数据库时,我们一般都在多的一端加上外键约束
在实体类同名包下相关xml文件中配置相关表属性,但是这样简单的配置只是两张普通表
通过在多的一端给表设置<many-to-one>标签来映射表间关系
<many-to-one name="classes" cascade="save-update" column="cid"></many-to-one>
在这里面,默认使用的字段是class,但也可以更改为cid.从而在主表中添加外键属性
但是这样如果不加上cascade="save-update"的话,添加数据必须先对class添加,然后才能对student表进行添加数据,而 cascade="save-update" 则是使用级联操作,保存student时自动保存class(cascade 有三种值 save-update all delete 但是all delete不适合使用,因为删除一个学生就删除一个班级,这是错误操作)
查询:
我们只查询student表,调用它的getClasses().getName()也可以拿到class的属性,这说明查询时,hibernate就把class自动查询出来了,所以实体类的配置文件最大的作用不是用来创建表,而是用来告诉hibernate如何加载数据的,
关联标签映射默认都是主键关联(当前关联字段去寻找对方表的主键)
②一对一映射
事例:husband-wife表关联
数据库设计时有两种设计思路:一是给非主键设置外键唯一约束,而是主键直接设置为另一表的外键
一对一主键关联映射
husband的主键就是wife的外键,husband的主键不能自动生成,需要依赖于wife的主键生成
给husband的id属性添加
<generator class="foreign">
<param name="property">wife</param>
</generator>
表示主键依赖于wife主键的创建
同同样,husband表配置加上<one-to-one name="wife" constrained="true"></one-to-one>
Wife表配置加上<one-to-one name="husband"></one-to-one>
constrained="true" 表示可以通过两者之间任意张表都可以查询到另一表的属性,否则只能单向查询属性(只有在一对一中可使用)。
一对一唯一外键关联映射
在多对一的基础上给外键加上唯一约束
Husband表 <many-to-one name="wife" column="wid" unique="true"></many-to-one>
Wife表 <one-to-one name="husband" property-ref="wife"></one-to-one>
如果没有加上property-ref="wife" 属性,这样创建表示没有问题的,但是加载数据会出现问题,因为one-to-one也是默认主键加载,而现在应该是外键加载,所以必须加上property-ref="wife" 代表制定关联哪个属性
一对一关联映射默认是级联的(cascade)
③一对多映射
事例:class-student表关联
创建class的实体类时,注定会有一个成员变量
Set<Student> students = new HashSet<Student>();(set里的数据是唯一的,set查询速度最快)
Class :<set name="students" inverse="true">
//-set中的key的含义不是在自己这张表里创建字段,而是在关联的表中创建字段
<key column="cid"></key>
<one-to-many class="Student"/>
</set>
Student <many-to-one name="classes" column="cid"></many-to-one>
测试时:
如果没有设置set的属性 inverse="true",
使用一对多会发出多余的update语句,因为先保存的是从表的数据
没有对应的主表的id,只能插入null值,再保存了主表的数据后
在发出update语句对从表的数据进行修改。效率很低
但是如果设置set的属性 inverse="true" 则把一对多转化为多对一处理
<!-- inverse叫做反转,含义是即便代码中使用的是一对多的方式就行保存
内部把控制权交给多对一,这样就不会发出多余的update语句了
-->
④多对多映射
事例:teacher-course表关联
借用中间表进行关联表
配置信息:设置统同一中间表,
Teacher: <set name="course" table="t_teacher_course">
<key column="tid"></key>
<many-to-many class="Course" column="cid"></many-to-many>
</set>
Course:<set name="teachers" table="t_teacher_course">
<key column="cid"></key>
<many-to-many class="Teacher" column="tid"></many-to-many>
</set>