hibernate入门(七)关联关系讨论_多对多关系映射
packagecom.asm.hibernate.domain;
importjava.util.Set;
public class Student {
??? private int id;
??? private String name;
??? private Set<Teacher> teachers;
}
packagecom.asm.hibernate.domain;
importjava.util.Set;
public class Teacher {
??? private int id;
??? private String name;
??? private Set<Student> students;
}
>>步骤二、为两个实体创建配置文件(省略了前面的xml文档声明内容):
Student.hbm.xml内容如下:
<hibernate-mapping
??? package="com.asm.hibernate.domain">
??? <class name="Student">
?????? <id name="id">
?????????? <generator class="native"/>
?????? </id>
?????? <propertyname="name"></property>
?????? <set name="teachers" table="teacher_student">
?????????? <key column="student_id" />
?????????? <many-to-many class="Student"column="teacher_id"/>
?????? </set>
??? </class>
Teacher.hbm.xml内容如下:
<hibernate-mapping
??? package="com.asm.hibernate.domain">
??? <class name="Teacher">
?????? <id name="id">
?????????? <generator class="native"/>
?????? </id>
?????? <propertyname="name"></property>
??????
?????? <set name="students" table="teacher_student">
?????????? <key column="teacher_id" />
?????????? <many-to-many class="Student"column="student_id"/>
?????? </set>
??? </class>
由于和Student.hbm.xml是类似的,这里不作说明,这样也就建立起了双向的多对多关联。
要注意他们所依赖的中间表为teacher_student,所以这里的<set>元素中的table属性和teacher映射文件相同,而特别要注意<key>和<many-to-many>中column中属性值的设定。
>>步骤三、在主配置文件中关联实体配置文件:只需要增加如下内容:
<mapping resource="com/asm/hibernate/domain/Teacher.hbm.xml" />
<mapping resource="com/asm/hibernate/domain/Student.hbm.xml" />
>>步骤四、编写测试文件ManyToManyTest.java:省略导入的包。
packagecom.asm.hibernate.test;
public class ManyToManyTest {
??? public static void main(String[] args) {
?????? add();
??? }
?
??? static void add() {
?????? Session s = null;
?????? Transaction tr = null;
?????? try {
?????????? s = HibernateUtil.getSession();
?????????? tr = s.beginTransaction();
?
?????????? Teacher t1 = new Teacher();
?????????? t1.setName("t1Name");
?
?????????? Teacher t2 = new Teacher();
?????????? t2.setName("t2Name");
?
?????????? Student s1 = new Student();
?????????? s1.setName("s1Name");
?
?????????? Student s2 = new Student();
?????????? s2.setName("s2Name");
?
?????????? // 再增加如下内容进行测试:
?????????? Set<Teacher> ts = new HashSet<Teacher>();
?????????? ts.add(t1);
?????????? ts.add(t2);
?????????? Set<Student> ss = new HashSet<Student>();
?????????? ss.add(s1);
?????????? ss.add(s2);
?
?????????? t1.setStudents(ss);
?????????? t2.setStudents(ss);
?
?????????? // s1.setTeachers(ts);
?????????? // s2.setTeachers(ts);
?????????? // 增加内容完
?????????? s.save(s1);
?????????? s.save(s2);
?????????? s.save(t1);
?????????? s.save(t2);
?????????? tr.commit();
?
?????? } finally {
?????????? if (s != null)
????????????? s.close();
?????? }
??? }
}
说明:注意以上注释掉的内容,如果去掉会出现异常。理解:加上增加的内容后再执行发现,在开启“数据库显示”功能后,发现控制台中新增加了四条插入语句,且是插入到中间表teacher_student中,在此处相当于告诉了每个学生所关联到的老师,而如果在mysql客户端执行“show create table teacher_student”,观察它的表结构并结合“去掉注释的报错说明”,就容易理解到为什么不能有注释掉的内容。另需要说明的是“多对多”在操作和性能方面都不太理想,所以它使用较少,一般我们会选择转换成“一对多”的模型,而Hiberante的“多对多”实现,可能也是转换成两个“一对多”来实现。