Hibernate关联关系映射之多对多关联关系
例如,在教师表中有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(); } } }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。