《Hibernate学习笔记十》:多对多关联关系详解

《Hibernate学习笔记十》:多对多关联关系

前面介绍了一对一、多对一和一对多的关联关系在Hibernate应如何实现,这篇博文就来介绍下最后一种关联关系:多对多。多对多关联关系在我们现实生活中的例子实在是太多太多,最典型的就是老师和学生的例子:一个老师可以教多个学生,而一个学生又可以被多个老师来教。

了解一点数据库的我们都知道,在数据库中表示多对多的关联关系,是借助于中间表来解决的。

如下:

《Hibernate学习笔记十》:多对多关联关系详解_第1张图片

还是和以往的思路一样,每一种关联关系都分为单向关联和双向关联,我们每种都会进行介绍,对于单向和双向关联,我们都会介绍用Annotation应如何来做,然后介绍用XXX.hbm.xml文件应如何来做。

1.多对多单向关联关系

单向关联,假设老师知道它要教多个学生,而学生并不知道他要被那些个老师教。下面就以基于这样一个假设来进行实现。

1.1 多对多单向关联关系Annotation实现

Student实体类

@Entity
public class Student {
    private int id;
    private String name;
    @Id
    @GeneratedValue
    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;
    }
}

Teacher类

老师知道他要教那些个学生,因此,在Teacher类中有一个Set容器。并使用注解@ManyToMany来进行修饰。

@Entity
public class Teacher {
    private int id;
    private String name;
    private Set<Student> students=new HashSet<Student>();
    @ManyToMany 
    public Set<Student> getStudents() {
        return students;
    }
    public void setStudents(Set<Student> students) {
        this.students = students;
    }
    @Id
    @GeneratedValue
    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;
    }
}

这样就建立了一个多对多单向的关联关系。

在控制台我们可以看到如下的建表语句:

Hibernate给我们生成了一个Teacher_Student的中间表,中间表的字段为Teacher_idStudent_id.

如果我们想自己制定中间表的表名,以及中间表的字段名,该怎么办呢?

使用注解@JoinTable来解决,具体代码如下:

@Entity
public class Teacher {
    private int id;
    private String name;
    private Set<Student> students=new HashSet<Student>();
    @ManyToMany 
    @JoinTable(name = "T_S",//设置中间表的名字,以及中间表的字段名
                joinColumns = {@JoinColumn(name="teacher_id")},
                inverseJoinColumns = @JoinColumn(name="student_id")
    )
    public Set<Student> getStudents() {
        return students;
    }
    public void setStudents(Set<Student> students) {
        this.students = students;
    }
    @Id
    @GeneratedValue
    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;
    }
}

测试结果如下:

1.2 多对多单向关联关系XXX.hbm.xml实现

这里主要看下两个xml文件。

Teacher.hbm.xml

关键点在这里:

<set name="students" table="T_S" > <!-- 指定表名为T_S -->
        <!-- key中 这个column指向的是Teacher这个表的外键名称,下面是指向另一外一个表的外键名称 -->
            <key column="teacher_id"></key> 
            <many-to-many class="com.hibernate.model.Student" column="student_id"/>
 </set>

完整内容如下:

<?xml version="1.0"?>
    <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    <hibernate-mapping package="com.hibernate.model">
    <class name="Teacher" table="teacher" >
        <id name="id" column="id">
            <generator class="native"/>
        </id>
        <property name="name" column="name"/>  
        <set name="students" table="T_S" > <!-- 指定表名为T_S -->
        <!-- key中 这个column指向的是Teacher这个表的外键名称,下面是指向另一外一个表的外键名称 -->
            <key column="teacher_id"></key> 
            <many-to-many class="com.hibernate.model.Student" column="student_id"/>
        </set> 
    </class>
    </hibernate-mapping>

Student.hbm.xml

<?xml version="1.0"?>
    <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    <hibernate-mapping package="com.hibernate.model">
    <class name="Student" table="student" >
        <id name="id" column="id">
            <generator class="native"/>
        </id>
        <property name="name" column="name"/>  
    </class>
    </hibernate-mapping>

这样就是采用了xml文件实现了多对多单向关联关系。

2、双向关联

2.1 多对多双向关联关系Annotation实现
在代码中,Student类和Teacher类都会有一个对方的Set容器,来表示每个学生知道有那几个老师教他们,每个老师知道他们需要教那几个学生。

Teacher类的代码不变

@Entity
public class Teacher {
    private int id;
    private String name;
    private Set<Student> students=new HashSet<Student>();
    @ManyToMany 
    @JoinTable(name = "T_S",//设置中间表的名字,以及中间表的字段名
                joinColumns = {@JoinColumn(name="teacher_id")},
                inverseJoinColumns = @JoinColumn(name="student_id")
    )
    public Set<Student> getStudents() {
        return students;
    }
    public void setStudents(Set<Student> students) {
        this.students = students;
    }
    @Id
    @GeneratedValue
    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类有一定变化,相比多对多单向关联

由于在Teacher类中,已经设置了关联,这边使用@ManyToMany(mappedBy = “students”)即可

@Entity
public class Student {
    private int id;
    private String name;
    private Set<Teacher> teachers=new HashSet<Teacher>();
    @ManyToMany(mappedBy = "students")
    public Set<Teacher> getTeachers() {
        return teachers;
    }
    public void setTeachers(Set<Teacher> teachers) {
        this.teachers = teachers;
    }
    @Id
    @GeneratedValue
    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;
    }
}

这样,就使用Annotation完成了多对多的双向关联。

2.2 多对多双向关联关系XXX.hbm.xml实现

主要涉及到的两个xml文件。

1、Teacher.hbm.xml文件

<?xml version="1.0"?>
    <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    <hibernate-mapping package="com.hibernate.model">
    <class name="Teacher" table="teacher" >
        <id name="id" column="id">
            <generator class="native"/>
        </id>
        <property name="name" column="name"/>  
        <set name="students" table="T_S" > <!-- 指定表名为T_S -->
        <!-- key中 这个column指向的是Teacher这个表的外键名称,下面是指向另一外一个表的外键名称 -->
            <key column="teacher_id"></key> 
            <many-to-many class="com.hibernate.model.Student" column="student_id"/>
        </set> 
    </class>
    </hibernate-mapping>

2、Student.hbm.xml

Student.hbm.xml文件与Teacher.hbm.xml文件基本一样。

<?xml version="1.0"?>
    <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    <hibernate-mapping package="com.hibernate.model">
    <class name="Student" table="student" >
        <id name="id" column="id">
            <generator class="native"/>
        </id>
        <property name="name" column="name"/>  
        <set name="teachers" table="T_S" > <!-- 指定表名为T_S -->
        <!-- key中 这个column指向的是Teacher这个表的外键名称,下面是指向另一外一个表的外键名称 -->
            <key column="student_id"></key> 
            <many-to-many class="com.hibernate.model.Teacher" column="teacher_id"/>
        </set> 
    </class>
    </hibernate-mapping>

这样,就完成了多对多关系的关联。

小结

在上面的学习过程中,多对多关联关系不难,借助于Hibernate还是比较好实现,至于如何来写注解的XXX.hbm.xml文件,我们都不需要记,会查文档就行,这里,提供一个Hibernate Annotation的文档连接:http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html_single/

你可能感兴趣的:(Hibernate,多对多,关联关系)