1.单向
一对多关联映射利用了多对一关联映射原理。
多对一关联映射:在多的一端加入一个外键指向一的一端,它维护的关系是多指向一;
一对多关联映射:在多的一端加入一个外键指向一的一端,它维护的关系是一指向多。
即两者的映射策略是相同的,只是看待问题的角度不同。
举例:Classes------》Student
(1)Student.java
package edu.study.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;
}
}
(2)Classes.java
package edu.study.hibernate;
import java.util.Set;
public class Classes {
private int id;
private String name;
private Set students;
public Set getStudents() {
return students;
}
public void setStudents(Set 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;
}
}
(3)Student.hbm.xml
<hibernate-mapping>
<class name="edu.study.hibernate.Student" table="t_student">
<id name="id">
<generator class="native"></generator>
</id>
<property name="name"></property>
</class>
</hibernate-mapping>
(4)Classes.hbm.xml
<hibernate-mapping package="edu.study.hibernate">
<class name="Classes" table="t_classes">
<id name="id">
<generator class="native"></generator>
</id>
<property name="name"></property>
<set name="students">
<key column="classesid"></key>
<one-to-many class="Student"/>
</set>
</class>
</hibernate-mapping>
测试保存:
Student student1=new Student();
student1.setName("小黄");
session.save(student1);
Student student2=new Student();
student2.setName("小雅");
session.save(student2);
Set students=new HashSet();
students.add(student1);
students.add(student2);
Classes classes=new Classes();
classes.setName("计算机2班");
classes.setStudents(students);
session.save(classes);
结果:
Hibernate: insert into t_student (name) values (?)
Hibernate: insert into t_student (name) values (?)
Hibernate: insert into t_classes (name) values (?)
Hibernate: update t_student set classesid=? where id=?
Hibernate: update t_student set classesid=? where id=?
这也是在一的一端维护关系的缺点,即需要发出额外的update语句来更新关系。因为是在Classes端维护关系的,而Student不知道是哪个班级的,所以需要额外的update语句。
因此一对多关联映射通常做成双向的。
2.双向
修改如下:
(1)Student.java
package edu.study.hibernate;
public class Student {
private int id;
private String name;
//新增
private Classes classes;
public Classes getClasses() {
return classes;
}
public void setClasses(Classes classes) {
this.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;
}
}
(2)Student.hbm.xml
<hibernate-mapping>
<class name="edu.study.hibernate.Student" table="t_student">
<id name="id">
<generator class="native"></generator>
</id>
<property name="name"></property>
<many-to-one name="classes" column="classesid"></many-to-one>
</class>
</hibernate-mapping>
这样以来,就可以先保存班级,然后学生就可以找到班级了。
测试代码:
Classes classes=new Classes();
classes.setName("软件2班");
session.save(classes);
Student student1=new Student();
student1.setName("小李");
student1.setClasses(classes);
session.save(student1);
Student student2=new Student();
student2.setName("小梁");
student2.setClasses(classes);
session.save(student2);
结果:
Hibernate: insert into t_classes (name) values (?)
Hibernate: insert into t_student (name, classesid) values (?, ?)
Hibernate: insert into t_student (name, classesid) values (?, ?)
即在多的一端维护关联关系,从而避免了在一的一端维护的弊端。
那么如何使一的一端失效呢?
解决办法:inverse,默认为false,设置为true,即由对方维护关联关系。
所以Classes.hbm.xml修改如下:
<set name="students" inverse="true">
<key column="classesid"></key>
<one-to-many class="Student"/>
</set>
添加了inverse属性。