one-to-many是一对多映射,如班级和学生的关系。
一对多也分为单向和双向之分。
package com.iteedu.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;
	}
}
<?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> <class name="com.iteedu.hibernate.Student" table="t_student"> <id name="id"> <generator class="native"/> </id> <property name="name"/> </class> </hibernate-mapping>
package com.iteedu.hibernate;
import java.util.Set;
public class Classes {
	private int id;
	private String name;
	private Set 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;
	}
	public Set getStudents() {
		return students;
	}
	public void setStudents(Set students) {
		this.students = students;
	}
}
这里的一对多用集合Set来实现。
<?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.iteedu.hibernate"> <class name="Classes" table="t_classes"> <id name="id"> <generator class="native"/> </id> <property name="name"/> <set name="students"> <key column="classesid"/> <one-to-many class="Student"/> </set> </class> </hibernate-mapping>
这里主要说一下set的配制。
<one-to-many/>
这是确定Set中是什么对象,也通过class找到类和对应映射文件,就可以找到数据库中的表了。
<key column="classesid"/>
找到表怎么做关联,这就要一个外键来指定,key就是指定外键的列名的,是数据库中的列的名称。
保存
session.beginTransaction();
Student student1 = new Student();
student1.setName("QQ");
session.save(student1);
Student student2 = new Student();
student2.setName("360");
session.save(student2);
Set students = new HashSet();
students.add(student1);
students.add(student2);
Classes classes = new Classes();
classes.setName("ITEEDU");
classes.setStudents(students);
//可以正确保存
session.save(classes);
session.getTransaction().commit();
加载
session.beginTransaction();
Classes classes = (Classes)session.load(Classes.class, 1);
System.out.println("classes.name=" + classes.getName());
Set students = classes.getStudents();
for (Iterator iter=students.iterator(); iter.hasNext();) {
    Student student = (Student)iter.next();
    System.out.println("student.name=" + student.getName());
}
session.getTransaction().commit();
一对多双向,一的一方不变,多的一方加上many-to-one配制。
private Classes classes;
public Classes getClasses() {
    return classes;
}
public void setClasses(Classes classes) {
    this.classes = classes;
}
<many-to-one name="classes" column="classesid"/>
其中column要和一的一端Set中的key相同。其实就是数据库要用同一个列关联。
保存
session.beginTransaction();
Classes classes = new Classes();
classes.setName("ITEEDU");
session.save(classes);
Student student1 = new Student();
student1.setName("QQ");
student1.setClasses(classes);
session.save(student1);
Student student2 = new Student();
student2.setName("360");
student2.setClasses(classes);
session.save(student2);
session.getTransaction().commit();
加载
session.beginTransaction();
Student student = (Student)session.load(Student.class, 1);
System.out.println("student.name=" + student.getName());
System.out.println("student.classes.name=" + student.getClasses().getName());
session.getTransaction().commit();
在一的一端维护关系的缺点:
如果将t_student表里的classesid字段设置为非空,则无法保存。
因为不是在student这一端维护关系,所以student不知道是哪个班的,所以需要发出多余的update语句来更新关系。
解决方法:
如果在一的一端维护一对多关联关系,hibernate会发出多余的udpate语句,所以我们一般在多的一端来维护关联关系。
关系反转inverse和级联cascade。
inverse主要用在一对多和多对多双向关联上,inverse可以被设置到集合标签<set>上,默认inverse为false,所以我们可以从一的一端和多的一端维护关联关系,如果设置成inverse为true,则我们只能从多的一端来维护关联关系。
<set name="students" inverse="true" cascade="all"> <key column="classesid"/> <one-to-many class="Student"/> </set>
保存示例:
session.beginTransaction();
Classes classes = new Classes();
classes.setName("ITEEDU");
Student student1 = new Student();
student1.setName("QQ");
student1.setClasses(classes);
Student student2 = new Student();
student2.setName("360");
student2.setClasses(classes);
Set students = new HashSet();
students.add(student1);
students.add(student2);
classes.setStudents(students);
session.save(classes);
session.getTransaction().commit();
在保存classes时,由于双向关联,学生设置了班级,所以先保存班级,再保存学生(级联后自动保存学生)。