多对多的映射:多个老师对应多个学生
由于此类操作较为繁琐,且浪费资源,较多的是将其更改为一对多的映射,即增加中间层,设计成多对多映射.
teacher.hbm.xml
<class name="Teacher">
<id name="id">
<generator class="native" />
</id>
<property name="name" unique="true" />
<set name="students" table="teacher_student">
<!-- 告诉Hibernate,集合中存放的是student,同时声明中间表的名称 -->
<key column="teacher_id"></key>
<many-to-many class="Student" column="student_id" />
</set>
</class>
<id name="id">
<generator class="native" />
</id>
<property name="name" unique="true" />
<set name="students" table="teacher_student">
<!-- 告诉Hibernate,集合中存放的是student,同时声明中间表的名称 -->
<key column="teacher_id"></key>
<many-to-many class="Student" column="student_id" />
</set>
</class>
student.hbm.xml
<class name="Student">
<id name="id">
<generator class="native" />
</id>
<property name="name" unique="true" />
<set name="teacher" table="teacher_student">
<key column="student_id" />
<many-to-many class="Teacher" column="teacher_id"/>
</set>
</class>
<id name="id">
<generator class="native" />
</id>
<property name="name" unique="true" />
<set name="teacher" table="teacher_student">
<key column="student_id" />
<many-to-many class="Teacher" column="teacher_id"/>
</set>
</class>
测试代码:
Set<Teacher> ts = new HashSet<Teacher>();
Teacher t1 = new Teacher();
t1.setName("t1 name");
Teacher t2 = new Teacher();
t2.setName("t2 name");
ts.add(t1);
ts.add(t2);
Set<Student> ss = new HashSet<Student>();
Student s1 = new Student();
s1.setName("s1 name");
Student s2 = new Student();
s2.setName("s2 name");
ss.add(s1);
ss.add(s2);
// 告诉学生他们的老师
s1.setTeacher(ts);
s2.setTeacher(ts);
// 告诉老师他们的学生
// t2.setStudents(ss);
s = HibernateUtils.getSession();
tx = s.beginTransaction();
s.save(t1);
s.save(t2);
s.save(s1);
s.save(s2);
tx.commit();
Teacher t1 = new Teacher();
t1.setName("t1 name");
Teacher t2 = new Teacher();
t2.setName("t2 name");
ts.add(t1);
ts.add(t2);
Set<Student> ss = new HashSet<Student>();
Student s1 = new Student();
s1.setName("s1 name");
Student s2 = new Student();
s2.setName("s2 name");
ss.add(s1);
ss.add(s2);
// 告诉学生他们的老师
s1.setTeacher(ts);
s2.setTeacher(ts);
// 告诉老师他们的学生
// t2.setStudents(ss);
s = HibernateUtils.getSession();
tx = s.beginTransaction();
s.save(t1);
s.save(t2);
s.save(s1);
s.save(s2);
tx.commit();
这里,特别的要留意,如果告诉学生他们的老师后,老师也就知道了他们的学生,如果这时候再告诉老师他们的学生,则会抛出主键冲突的异常.
原因是这样:
由于告诉学生他们的老师时,Hibernate更新了中间表:teacher_student,而teacher_student是由teacher_id和student_id联合组成的联合主键,此时该主键由学生维护.
转载于:https://blog.51cto.com/xiaosa/131412