Hibernate多对多映射
Hibernate多对多映射
昨夜西风凋碧树,独上高楼,望尽天涯路。
衣带渐宽终不悔,为君消得人憔悴。
众里寻他千百度,蓦然回首,那人却在灯火阑珊处。
-------------王国维《人间词话》
古今成大事者、大学问者首先要树立明确的目标,即使长路漫漫也要下决心走下这条路,这是一个人在孤独中需找理想,寻找生命的落脚点的痛苦时刻。然后执着的追求,忘我的奋斗,直到憔悴消瘦连衣服都变得宽大,这一切都是为了心中的梦想。经过不断的磨练,多次失败某时刻忽然灵犀一点,参透真谛。
一直都很欣赏王大师总结的这篇文章,一个人学习境界的唯美表述使我常常沉浸在这种书画般的境界。自己时常又不是在高处独自登上高楼,单薄的衣服挡不住习习秋风,放眼望去繁华的灯火哪里是我的归宿?为了完成一些有趣的事,何尝不是在电脑前通宵达旦,炯炯有神的目光中隐隐泛着充满智慧和激情的纹路?且不说自己如何如何,自己依旧在缓慢的成长抵不过身边那些向着太阳愤怒生长的麦子。
废话不多说,这么文艺的也只能在自己心血来潮的时候来几句 ,博客博客。。。
自己再次总结之前学过的Hibernate多对多映射,在我们具体的业务场景中有很多的着这种情况。比如学生和教师的对应关系,一个学生可以对应多个教师,一个教师可以对应多个学生。
下面是我用PowerDesigner做的类图的对应关系
然后是相应的数据库模型,在这种多对多的情况下会出现一个中间表。
然后生成代码如下:
Student.java
package com.school.domain; import java.util.HashSet; /*********************************************************************** * Module: Student.java * Author: ZDX * Purpose: Defines the Class Student ***********************************************************************/ /** @pdOid 250f1280-ff07-4a23-861a-388479f12ca7 */ public class Student { /** @pdOid 73a45190-7b2e-4455-9135-32f62e6865ce */ private Integer studentId; /** @pdOid 063f1ccc-8682-4727-8d26-2724d9e5c907 */ private String name; /** * @pdRoleInfo migr=no name=Teacher assc=association1 coll=java.util.Set * impl=java.util.HashSet mult=1..* side=A */ private java.util.Set<Teacher> teacherSet=new HashSet<Teacher>(); public Student() { // TODO Auto-generated constructor stub } public Student(String name) { this.name = name; } /******************************get和set方法*************/ }
Teacher.java
package com.school.domain; import java.util.HashSet; /*********************************************************************** * Module: Teacher.java * Author: ZDX * Purpose: Defines the Class Teacher ***********************************************************************/ /** @pdOid 16d32ee4-1b55-4ac8-aa68-3ca9d0df72d0 */ public class Teacher { /** @pdOid 26587481-5822-4b3a-9763-0ae2ef690853 */ private Integer teacherId; /** @pdOid eaf2ad6c-4bf3-4321-863e-345f78962fad */ private String name; /** @pdRoleInfo migr=no name=Student assc=association1 coll=java.util.Set impl=java.util.HashSet mult=1..* */ private java.util.Set<Student> studentSet=new HashSet<Student>(); public Teacher() { // TODO Auto-generated constructor stub } /*****************get和set方法*********************/ }
然后就是比较关键的xml配置了
首先是Student.xml如下:
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping default-lazy="false"> <class name="com.school.domain.Student" table="student"> <id name="studentId"> <generator class="native"></generator> </id> <property name="name"></property> <!-- 1.中间表的名称 2.集合外键(引用本表主键的那个外键) 3.引用关联实体表主键的那个外键 4.关联对方实体的类型 --> <set name="teacherSet" table="teacher_student"> <key column="studentId"></key> <many-to-many class="com.school.domain.Teacher" column="teacherId"></many-to-many> </set> </class> </hibernate-mapping>
首先是Teacher.xml如下:
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping default-lazy="false"> <class name="com.school.domain.Teacher" table="teacher"> <id name="teacherId"> <generator class="native"></generator> </id> <property name="name"></property> <!-- 1.中间表的名称 2.集合外键(引用本表主键的那个外键) 3.引用关联实体表主键的那个外键 4.关联对方实体的类型 --> <set name="studentSet" table="teacher_student"> <key column="teacherId"></key> <many-to-many class="com.school.domain.Student" column="studentId"></many-to-many> </set> </class> </hibernate-mapping>
下面是测试方法:
public class StudentDaoTest { StudentDao dao=new StudentDao(); TeacherDao teacherDao=new TeacherDao(); @Test public void testSaveStudent() { /**************************new Student*******************************/ Student student1=new Student("张三"); Student student2=new Student("李四"); Student student3=new Student("王五"); Student student4=new Student("杨六"); Set<Student> students=new HashSet<Student>(); students.add(student1); students.add(student2); students.add(student3); students.add(student4); /**************************new Teacher*******************************/ Teacher teacher1=new Teacher("伟帅"); Teacher teacher2=new Teacher("铁哥"); Teacher teacher3=new Teacher("松哥"); Set<Teacher> teachers=new HashSet<Teacher>(); teachers.add(teacher1); teachers.add(teacher2); teachers.add(teacher3); /*************给老师和学生设置对应关系*****************/ teacher1.setStudentSet(students); teacher2.setStudentSet(students); teacher3.setStudentSet(students); /***********************保存到数据库*****************/ dao.saveStudent(student1); dao.saveStudent(student2); dao.saveStudent(student3); dao.saveStudent(student4); teacherDao.saveTeacher(teacher1); teacherDao.saveTeacher(teacher2); teacherDao.saveTeacher(teacher3); } }
上面这种方式是在不设置级联的情况下进行的所以要同时保存student和teacher
dao.saveStudent(student1); dao.saveStudent(student2); dao.saveStudent(student3); dao.saveStudent(student4); teacherDao.saveTeacher(teacher1); teacherDao.saveTeacher(teacher2); teacherDao.saveTeacher(teacher3);
如果将级联设置为如下:
save-update:级联保存(load以后如果子对象发生了更新,也会级联更新). 但它不会级联删除
all-delete-orphan: 在解除父子关系时,自动删除不属于父对象的子对象, 也支持级联删除和级联保存更新。
那么只需要执行
/***********************保存到数据库*****************/ // dao.saveStudent(student1); // dao.saveStudent(student2); // dao.saveStudent(student3); // dao.saveStudent(student4); teacherDao.saveTeacher(teacher1); teacherDao.saveTeacher(teacher2); teacherDao.saveTeacher(teacher3);
配置只需要在set参数配置中添加属性就可以如下:
Student.hbm.xml:
<set name="teacherSet" table="teacher_student" cascade="save-update"> <key column="studentId"></key> <many-to-many class="com.school.domain.Teacher" column="teacherId"></many-to-many> </set>
Teacher.hbm.xml
<set name="studentSet" table="teacher_student" cascade="save-update"> <key column="teacherId"></key> <many-to-many class="com.school.domain.Student" column="studentId"></many-to-many> </set>
以上就是Hibernate的多对多映射。