J2EE系列之Hibernate4学习笔记(十四)--多对多映射

来源:互联网 发布:朝鲜没有网络吗 编辑:程序博客网 时间:2024/06/11 02:21

以学生课程这个多对多映射为例,每个学生可以选多门课程,而每门课程又可以被多个学生选择。多对多映射可以分为两种:单向的多对多和双向的多对多

一、单向的多对多映射:这里以学生为主,可以查询每个学生选修的多门课程,但是不能查询选修某个课程的学生

1.新建学生类Student:

package com.test.model;import java.util.HashSet;import java.util.Set;public class Student {private int id;private String name;private Set<Course> courses = new HashSet<Course>();public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Set<Course> getCourses() {return courses;}public void setCourses(Set<Course> courses) {this.courses = courses;}}
这个类中包括id,学生名称,选修的课程三个属性。

2.新建课程类Course:

package com.test.model;public class Course {private int id;private String name;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}}

课程类中有id和课程名称两个属性。


3.编写Student的映射文件:

<?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 package="com.test.model"><class name="Student" table="t_student"><id name="id" column="studentId"><generator class="native"></generator></id><property name="name" column="studentName"></property><set name="courses" table="student_courses" cascade="save-update"><key column="student_id"></key><many-to-many class="com.test.model.Course" column="course_id"></many-to-many></set></class></hibernate-mapping>

这里重点说一下<set>标签,使用<set>标签定义学生类中的集合元素courses,把这个元素重新成一张新的数据表student_courses,student_courses这个数据表的外键student_id映射t_student表的主键,这个表的外键course_id映射Course类数据表的主键。cascade属性值为save-update表明当保存t_student表中的数据时级联保存student_courses中的数据。

4.编写Course类的映射文件:

<?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 package="com.test.model"><class name="Course" table="t_course"><id name="id" column="courseId"><generator class="native"></generator></id><property name="name" column="courseName"></property></class></hibernate-mapping>

这个表没啥好说的。


5.把这两个映射文件添加到配置文件中。写测试函数:

@Testpublic void testSave1(){Course course1 = new Course();course1.setName("语文");Course course2 = new Course();course2.setName("数学");Student student1 = new Student();student1.setName("张三");student1.getCourses().add(course1);student1.getCourses().add(course2);Student student2 = new Student();student2.setName("李四");student2.getCourses().add(course1);student2.getCourses().add(course2);session.save(student1);session.save(student2);}@Testpublic void testLoad1(){Student student = (Student)session.get(Student.class, 1);Set<Course> courses = (Set<Course>) student.getCourses();Iterator it = courses.iterator();while(it.hasNext()){Course c = (Course) it.next();System.out.println(c.getName());}}

运行testSave1方法,生成的数据库表结构为:

生成的表中的数据为:

                       


运行testLoad1方法,查询学号为1的学生选择的课程:


2.双向多对多映射

1.新建学生类Student2:

package com.test.model;import java.util.HashSet;import java.util.Set;public class Student2 {private int id;private String name;private Set<Course2> courses = new HashSet<Course2>();public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Set<Course2> getCourses() {return courses;}public void setCourses(Set<Course2> courses) {this.courses = courses;}}

2.新建课程类Course2:

package com.test.model;import java.util.HashSet;import java.util.Set;public class Course2 {private int id;private String name;private Set<Student2> students = new HashSet<Student2>();public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Set<Student2> getStudents() {return students;}public void setStudents(Set<Student2> students) {this.students = students;}}

这里为了实现双向查询,课程类中添加了学生类的集合属性。

3.编写学生类映射文件:

<?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 package="com.test.model"><class name="Student2" table="t_student2"><id name="id" column="studentId"><generator class="native"></generator></id><property name="name" column="studentName"></property><set name="courses" table="student_courses2" cascade="save-update"><key column="student_id"></key><many-to-many class="com.test.model.Course2" column="course_id"></many-to-many></set></class></hibernate-mapping>

4.编写课程类映射文件:

<?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 package="com.test.model"><class name="Course2" table="t_course2"><id name="id" column="courseId"><generator class="native"></generator></id><property name="name" column="courseName"></property><set name="students" table="student_courses2" inverse="true"><key column="course_id"></key><many-to-many class="com.test.model.Student2" column="student_id"></many-to-many></set></class></hibernate-mapping>

这里<set>标签中设置了inverse的值为true,这表示又学生类一端来维护表关系。


5.以上两个映射文件添加到配置文件中,写测试方法:

@Testpublic void testSave2(){Course2 course1 = new Course2();course1.setName("语文");Course2 course2 = new Course2();course2.setName("数学");Student2 student1 = new Student2();student1.setName("张三");student1.getCourses().add(course1);student1.getCourses().add(course2);Student2 student2 = new Student2();student2.setName("李四");student2.getCourses().add(course1);student2.getCourses().add(course2);session.save(student1);session.save(student2);}@Testpublic void testLoad2(){Course2 course = (Course2) session.get(Course2.class, 1);Set<Student2> students = (Set<Student2>)course.getStudents();Iterator it = students.iterator();while(it.hasNext()){Student2 s = (Student2) it.next();System.out.println(s.getName());}}

运行testSave2方法,生成的表结构为:

生成的数据为:

                    

运行testLoad2方法,查询选择了语文课程的学生:



阅读全文
0 0
原创粉丝点击