您的位置:首页 > 其它

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

2016-05-07 17:06 204 查看

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

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

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

如下:



还是和以往的思路一样,每一种关联关系都分为单向关联和双向关联,我们每种都会进行介绍,对于单向和双向关联,我们都会介绍用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_id
Student_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/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: