Hibernate——关系映射之多对多

关系映射之多对多

多对多的关系在操作和性能方面都不太理想,所以多对多的映射使用较少,实际使用中最好转换成一对多的对象模型;Hibernate会为我们创建中间表,转换成两个一对多。

经典案例:学生<–>选课,如下将学生选课关系用中间表来关联。

多对多关系的转换

这个案例在我们学习HQL语句的时候也用过,所以这里再简要介绍一下。更多的细节请参考【Hibernate——HQL语句

三个对象的domain对象以及关系映射文件如下:

  • Student对象以及关系映射文件:
package com.gavin.domain;

import java.util.Set;

public class Student {
    private int id;
    private String name;
    private Set<StudentCourse> studentCourseSet;

    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<StudentCourse> getStudentCourseSet() {
        return studentCourseSet;
    }

    public void setStudentCourseSet(Set<StudentCourse> studentCourseSet) {
        this.studentCourseSet = studentCourseSet;
    }
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD//EN"
        "http://hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.gavin.domain.Student" table="student" schema="hibernate">
        <id name="id" type="java.lang.Integer" column="id">
            <generator class="increment"/>
        </id>
        <property name="name" column="name" type="java.lang.String"/>
        <set name="studentCourseSet">
            <key column="sid"></key>
            <one-to-many class="com.gavin.domain.StudentCourse"/>
        </set>
    </class>
</hibernate-mapping>
  • Course对象以及关系映射文件:
package com.gavin.domain;

import java.util.Set;

public class Course {
    private int id;
    private String name;
    private Set<StudentCourse> studentCourseSet;

    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<StudentCourse> getStudentCourseSet() {
        return studentCourseSet;
    }

    public void setStudentCourseSet(Set<StudentCourse> studentCourseSet) {
        this.studentCourseSet = studentCourseSet;
    }
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD//EN"
        "http://hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.gavin.domain">
    <class name="com.gavin.domain.Course" table="course" schema="hibernate">
        <id name="id" column="id" type="java.lang.Integer">
            <generator class="increment"/>
        </id>
        <property name="name" column="name" type="java.lang.String"/>
        <set name="studentCourseSet">
            <key column="cid"></key>
            <one-to-many class="com.gavin.domain.StudentCourse"></one-to-many>
        </set>
    </class>
</hibernate-mapping>
  • StudentCourse对象以及关系映射文件:
package com.gavin.domain;

public class StudentCourse {
    private int id;
    private Student student;
    private Course course;
    private int grade;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public Student getStudent() {
        return student;
    }

    public void setStudent(Student student) {
        this.student = student;
    }

    public Course getCourse() {
        return course;
    }

    public void setCourse(Course course) {
        this.course = course;
    }

    public int getGrade() {
        return grade;
    }

    public void setGrade(int grade) {
        this.grade = grade;
    }
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD//EN"
        "http://hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.gavin.domain.StudentCourse" table="studcourse" schema="hibernate">
        <id name="id" column="id" type="java.lang.Integer">
            <generator class="increment"/>
        </id>
        <property name="grade" type="java.lang.Integer" column="grade"/>
        <many-to-one name="student" column="sid"/>
        <many-to-one name="course" column="cid"/>
    </class>
</hibernate-mapping>
  • 测试代码:
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();

Student student = new Student();
student.setName("虾米");

Course course = new Course();
course.setName("数学");

StudentCourse studentCourse = new StudentCourse();
studentCourse.setStudent(student);
studentCourse.setCourse(course);
studentCourse.setGrade(89);

session.save(student);
session.save(course);
session.save(studentCourse);

transaction.commit();
  • Hibernate生成的SQL语句为:
Hibernate: drop table if exists course
Hibernate: drop table if exists studcourse
Hibernate: drop table if exists student
Hibernate: create table course (id integer not null, name varchar(255), primary key (id)) engine=MyISAM
Hibernate: create table studcourse (id integer not null, grade integer, sid integer, cid integer, primary key (id)) engine=MyISAM
Hibernate: create table student (id integer not null, name varchar(255), primary key (id)) engine=MyISAM
Hibernate: alter table studcourse add constraint FK3e0p086wyy1y3198jmcl1p07e foreign key (sid) references student (id)
Hibernate: alter table studcourse add constraint FKdxogu0d4je13yayrhem591hvn foreign key (cid) references course (id)
Hibernate: select max(id) from student
Hibernate: select max(id) from course
Hibernate: select max(id) from studcourse
Hibernate: insert into student (name, id) values (?, ?)
Hibernate: insert into course (name, id) values (?, ?)
Hibernate: insert into studcourse (grade, sid, cid, id) values (?, ?, ?, ?)
  • 生成的表结构如下:

这里写图片描述

猜你喜欢

转载自blog.csdn.net/gggavin/article/details/79511204