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的多对多映射。