Hibernate關聯關系映射之多對多關聯關系
來源:程序員人生 發布時間:2014-10-03 08:00:00 閱讀次數:2534次
本次仍然使用一個示例的方式進行演示,學生與教師之間的關系就是一個典型的多對多關系,一個教師可以有多個學生,同樣一個學生也可以有多個教師。在數據庫中存儲需要一張學生表存儲學生信息,一個教師表存儲教師信息,為了表示他們之間的關系我們需要一個中間表來表示他們之間的聯系。
例如,在教師表中有id,name兩個屬性,學生表中同樣有id,name兩個屬性。教師表中有兩條記錄分別是(1,董老師),(2,李老師);學生表中同樣有兩條(1,張三),(2,李四)。在中間表中有兩個字段(teacherId,studentId),這兩個字段構成一個聯合主鍵,同時這兩個字段又是教師表和學生表的外鍵,老師和學生進行關聯的時候直接插入關聯的老師和學生的id在中間表內即可,例如在中間表中插入(1,1)表示董老師與張三進行關聯,插入(1,2)表示董老師與李四關聯。
下面我們看一下Teacher類和Student類
package entity;
import java.util.HashSet;
import java.util.Set;
public class Teacher {
private Long id;
private String name;
private Set<Student> students = new HashSet<Student>();
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Student> getStudents() {
return students;
}
public void setStudents(Set<Student> students) {
this.students = students;
}
}
package entity;
import java.util.HashSet;
import java.util.Set;
public class Student {
private Long id;
private String name;
private Set<Teacher> teachers = new HashSet<Teacher>();
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Teacher> getTeachers() {
return teachers;
}
public void setTeachers(Set<Teacher> teachers) {
this.teachers = teachers;
}
}
在POJO類中仍然使用集合表示有多條記錄。
下面在看一個他們的映射配置文件
首先看Teacher.hbm.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="entity.Teacher" table="Teacher" schema="MYHR">
<id name="id" type="long">
<column name="ID"/>
<generator class="assigned" />
</id>
<property name="name" type="string">
<column name="NAME" not-null="true" />
</property>
<!-- students屬性,Set集合,表示本類與Student類的多對多關系 -->
<set name="students" table="teacher_student" inverse="false">
<key column="teacherId" />
<many-to-many class="entity.Student" column="studentId"/>
</set>
</class>
</hibernate-mapping>
類中的Set類型的屬性在映射配置文件中仍然使用<set>標簽進行映射,在<set>標簽中使用<many-to-many>表示他們之間的關系是多對多。
然后看Student.hbm.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="entity.Student" table="Student" schema="MYHR">
<id name="id" type="long">
<column name="ID" />
<generator class="assigned" />
</id>
<property name="name" type="string">
<column name="NAME" not-null="true" />
</property>
<!-- teachers屬性, Set集合,表示本類與Teacher類的多對多關聯關系-->
<!-- table:是實現多對多映射的中間表 -->
<!-- key:集合外鍵(引用當前表主鍵的那個外鍵) -->
<set name="teachers" table="teacher_student">
<key column="studentId" />
<many-to-many class="entity.Teacher" column="teacherId"/>
</set>
</class>
</hibernate-mapping>
這樣,教師和學生之間的多對多關聯映射就配置完了,下面看一下測試類。這里使用JUtil進行測試
package test;
import static org.junit.Assert.*;
import java.util.Iterator;
import java.util.Set;
import org.hibernate.Session;
import org.hibernate.Transaction;
import entity.Student;
import entity.Teacher;
import factory.HibernateSessionFactory;
public class Test {
private Session session = null;
private Transaction tran = null;
// 存儲對象
@org.junit.Test
public void save() {
session = HibernateSessionFactory.getSession();
tran = session.beginTransaction();
try {
Teacher teacher = new Teacher();
teacher.setId(1L);
teacher.setName("董老師");
Teacher t2 = new Teacher();
t2.setId(2l);
t2.setName("李老師");
Student s1 = new Student();
s1.setId(1L);
s1.setName("李四");
Student s2 = new Student();
s2.setId(2l);
s2.setName("張三");
teacher.getStudents().add(s1);
teacher.getStudents().add(s2);
t2.getStudents().add(s1);
t2.getStudents().add(s2);
s1.getTeachers().add(teacher);
s1.getTeachers().add(t2);
s2.getTeachers().add(teacher);
s2.getTeachers().add(t2);
session.save(teacher);
session.save(t2);
session.save(s1);
session.save(s2);
tran.commit();
} catch (Exception e) {
tran.rollback();
}
}
// 獲取老師信息
@org.junit.Test
public void GetTeacher() {
session = HibernateSessionFactory.getSession();
tran = session.beginTransaction();
try {
Teacher teacher = (Teacher) session.get(Teacher.class, 1l);
Set<Student> set = teacher.getStudents();
System.out.println(teacher.getName() + "的學生是:");
Iterator<Student> it = set.iterator();
while (it.hasNext()) {
Student s = it.next();
System.out.println(s.getName());
}
tran.commit();
} catch (Exception e) {
tran.rollback();
}
}
// 解除關聯關系
@org.junit.Test
public void RemoveRelation() {
session = HibernateSessionFactory.getSession();
tran = session.beginTransaction();
try {
Student s = (Student) session.get(Student.class, 1l);
Teacher teacher = (Teacher) session.get(Teacher.class, 1l);
// 如果Teacher的inverse屬性為false可以解除,如果為true不可以解除
teacher.getStudents().remove(s);
tran.commit();
} catch (Exception e) {
tran.rollback();
}
}
// 刪除關聯關系
@org.junit.Test
public void DeleteRelation() {
session = HibernateSessionFactory.getSession();
tran = session.beginTransaction();
try {
Teacher teacher = (Teacher) session.get(Teacher.class, 2l);
// 當teacher的inverse屬性為false時,可以將教師信息刪除,并且將中間表中相關記錄刪除
// 當inverse屬性為true時將教師信息刪除時拋出異常
session.delete(teacher);
tran.commit();
} catch (Exception e) {
tran.rollback();
}
}
}
生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈