Hibernate学习8—Hibernate 映射关系(多对多)
第二节:Hibernate 多对多映射关系实现
比如学生和课程是多对多的关系;
一个学生可以选多个课程;
一个课程可以被多个学生选中,所以是多对多的关系;
1,多对多单向实现:
单向关系:
这里通过学生可以获取这个学生选修的课程;
但是通过课程无法获取选修这门课程的学生;
Student.java:
package com.cy.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; } }
Course.java:
package com.cy.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; } }
Student.hbm.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 package="com.cy.model"> <class name="Student" table="t_student"> <id name="id" column="studentId"> <generator class="native"></generator> </id> <property name="name" column="studentName"></property> <!-- 多对多没法用两个表来实现,必须借助第三张表,中间表(student_course) key column="student_id"表示学生课程表中的一个外键student_id关联学生表的主键 --> <set name="courses" table="student_course" cascade="save-update"> <key column="student_id"></key> <!-- many to many映射的另外一张表 student_course的外键course_id关联course表的主键 --> <many-to-many class="com.cy.model.Course" column="course_id"></many-to-many> </set> </class> </hibernate-mapping>
Course.hbm.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 package="com.cy.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>
测试代码:
StudentTest.java:
package com.cy.service; import java.util.Set; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.junit.After; import org.junit.Before; import org.junit.Test; import com.cy.model.Course; import com.cy.model.Student; import com.cy.util.HibernateUtil; public class StudentTest { private SessionFactory sessionFactory=HibernateUtil.getSessionFactory(); private Session session; @Before public void setUp() throws Exception { session=sessionFactory.openSession(); session.beginTransaction(); } @After public void tearDown() throws Exception { session.getTransaction().commit(); session.close(); } @Test public 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); } /** * 获取张三选修的课程 */ @Test public void testLoad1(){ Student s = (Student) session.get(Student.class, 1); Set<Course> courses = s.getCourses(); for(Course course : courses) { System.out.println(course.getName()); } } }
查看生成的表结构:
student_course的建表语句:
插入数据后:
t_student:
t_course:
student_course:
2,多对多双向实现:
通过学生可以获取这个学生选修的课程;
通过课程可以获取选修这门课程的学生;
Student2.java:
package com.cy.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; } }
Course2.java:
package com.cy.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; } }
Student2.hbm.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 package="com.cy.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_course2" cascade="save-update"> <key column="student_id"></key> <many-to-many class="com.cy.model.Course2" column="course_id"></many-to-many> </set> </class> </hibernate-mapping>
Course2.hbm.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 package="com.cy.model"> <class name="Course2" table="t_course2"> <id name="id" column="courseId"> <generator class="native"></generator> </id> <property name="name" column="courseName"></property> <!-- inverse=true: 在双向关系中,由学生端来维护关联关系 --> <set name="students" table="student_course2" inverse="true"> <key column="course_id"></key> <many-to-many class="com.cy.model.Student2" column="student_id"></many-to-many> </set> </class> </hibernate-mapping>
测试代码:
@Test public 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); } /** * 获取选修 语文 这门课的学生 */ @Test public void testLoad2(){ Course2 course = (Course2) session.get(Course2.class, 1); Iterator<Student2> students = course.getStudents().iterator(); while(students.hasNext()){ Student2 s = students.next(); System.out.println(s.getName()); } }
查看生成的表结构:
表的结构、插入后的数据,都和单向关系中创建的一模一样;
区别就是,现在可以从课程获取到选修这门课程的学生了。