关联映射就是将关联关系映射到数据库里,在对象模型中就是一个或多个引用。
一、Hibernate多对一关联映射:就是在“多”的一端加外键,指向“一”的一端。
比如多个雇员对应一个部门,多个用户对应一个级别等等,都是多对一关系
1、在对应实体类中添加要关联的实体类对象,并创建getter和setter方法
public class Employee {
private int id;
private String username;
private String password;
private String nickname;
private double salary;//薪水
private Department dept;//对应实体类:部门
public Department getDept() {
return dept;
}
public void setDept(Department dept) {
this.dept = dept;
}
//...此处省略其他方法
}
2、在当前实体类的映射文件中Employee.hbm.xml文件中添加
<many-to-one name="dept" column="id_dept"></many-to-one>
此时运行测试代码就可以看到数据库中添加的数据了。
二、Hibernate双向一对多关联映射:让多的一端来维护关系。
主要是解决一对多单向关联的缺陷,而不是需求驱动的。
1、在映射一的基础上,添加一对多关联映射实现双向。
在部门类Department中添加private Set<Employee> empl;
并添加getter和setter方法。
2.在当前实体类的映射文件中Department.hbm.xml文件中添加
<!-- Department中的属性 cascade级联操作-->
<set name="empl" cascade="save-update" lazy="extra">
<key column="id_dept" />
<one-to-many class="Employee"/>
</set>
注:
- 在一的一端的集合上采用key标签,可以使得多的一端加入一个外键。
- 在多的一端采用many-to-one标签。
- key标签和many-to-one标签加入的字段保持一致,否则会产生数据混乱。
补充:
1、cascade属性的可能值有
all: 所有情况下均进行关联操作,即save-update和delete。
none: 所有情况下均不进行关联操作。这是默认值。
save-update: 在执行save/update/saveOrUpdate时进行关联操作。
delete: 在执行delete 时进行关联操作。
all-delete-orphan: 当一个节点在对象图中成为孤儿节点时,删除该节点。比如在一个一对多的关系中,Student包含多个book,当在对象关系中删除一个book时,此book即成为孤儿节点
2、hibernate集合属性的懒加载策略:
在集合属性上,可以配置懒加载策略,取值为:true/false/extra
true:默认取值,它的意思是只有在调用这个集合获取里面的元素对象时,才发出查询语句,加载其 集合元素的数据
false:取消懒加载特性,即在加载对象的同时,就发出第二条查询语句加载其关联集合的数据
extra:一种比较聪明的懒加载策略,即调用集合的size/contains等方法的时候,hibernate并不会去加载整个集合的数据,而是发出一条聪明的SQL语句,以便获得需要的值,只有在真正需要用到这些集合元素对象数据的时候,才去发出查询语句加载所有对象的数据
三、Hibernate单向的一对一主键关联映射:就是让两个实体的主键一样,就不需要加入多余的字段了。
比如一个学生对应一个身份证号,一个学生对应一条户口信息等等,都是一对一关联映射。
1、Person实体里要持有IdCard的引用。在Person实体里加入属性:Private IdCard idCard;
2、Person端维护关系,所以需要重点看Person的配置文件,Person.hbm.xml通俗来讲 ,就是就是Person中的Id既为主键又为外键。
所以需要修改Person中的id标签:通俗来讲是告诉Person里的id去关联哪个实体里的id。
此处的foreign生成策略,会取得关联对象的标识。
此处的property标签内是关联对象。
<id name="id">
<generator class="foreign">
<param name="property">idCard</param>
</generator>
</id>
3、在Person.hbm.xml中添加关联关系的标签:<one-to-one name="idCard" constrained="true"><one-to-one/>
这里的one-to-one标签指示hibernate如何加载其关联对象,默认根据主键加载也就是拿到关系字段值,根据对端的主键来加载关联对象。
这里的constrained=”true”表示当前主键Person的id主键,还是一个外键,参照了对应端的主键IdCard的id主键,会生成外键约束语句。
注:采用foreign映射策略在保存person对象的同时也会保存关联的对象,也就是idCard,他们之间还有级联关系。但是反之就不可以,也就是说,如果只保存IdCard对象,是会出错的,不会保存Person对象,因为关系的维护端在Person端,IdCard根本就不知道Person的存在。主键关联映射有弊端,不好维护。
四、Hibernate单向的一对一外键关联映射:一对一主键关联不好维护,用外键关联对象比较好。原理:多对一的特殊情况
1、Person.java是实体里有IdCard的引用,即加入属性:private IdCard idCard;IdCard.java里没有Person引用。
2、配置文件:IdCard.hbm.xml里都是普通属性。Person.hbm.xml的主键生成策略需要改变:<generator class="native"/>
使用标签many-to-one和unique : <many-to-one name="idCard" unique="true"/>
,这样就限制了多的一端的唯一性。
注:这里需要先保存IdCard.否则报错。
五、Hibernate双向一对一唯一外键关联:如果有需求要求的情况下,也可以建立双向的外键关联。
1、在Person和IdCard里添加对应端的引用,即添加相应属性。
2、person.hbm.xml和Hibernate单向的一对一外键关联映射中一样,修改IdCard.hbm.xml文件,添加one-to-one标签:<one-to-one name="person" property-ref="idCard"></one-to-one>.
注:必须指定one-to-one标签中的property-ref属性为关系字段的名称。
六、Hibernate双向多对多关联映射
通常一般采用<many to one>
和<one to many>
建立中间变量实现多对多映射。中间量实现<one to many>
。