hibernate系列九:多对多关联配置及案例(一)
2017-11-29 23:29
381 查看
前面已介绍了映射一对多和多对一关联关系的方法,这是软件开发中最常见的关联关系。下面将介绍另一种关联关系的映射:多对多关联。
以Course(课程)与Student(学生)类的关系为例,介绍映射多对多关联。一门课程需要多位学生参与,一位学生可能选修多门课程,构成了课程和学生之间的多对多的关系。Course表(课程)、Student表(学生)如图6.4所示。在关系数据模型中,无法直接表达Course表和 Student表之间的多对多关系,需要创建一个连接表Study(学习表)。它同时参照Course表和Student表,下图显示了这3张表的结构。
![](http://img.blog.csdn.net/20171129231938152?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd3g1MDQwMjU3/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
Study表以sno字段和cno字段作为联合主键。此外,cno字段作为外键参照Course表,而sno字段作为外键参照Student表。
根据业务需要,可以配置课程和学生的单向多对多关联,也可以配置课程和学生的双向多对多关联。接下来详细讲解这两种配置。
1. 配置单向多对多关联
假定仅建立从CourseBean(课程)类到StudentBean(学生)类的单向多对多关联。在CourseBean类中需要定义集合类型students属性,而在StudentBean类中不需要定义集合类型的courses属性。下图显示了CourseBean类和StudentBean类的关联关系。
![](http://img.blog.csdn.net/20171129232050026?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd3g1MDQwMjU3/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
在CourseBean类中定义students属性代码如下所示:
public class CourseBean implementsSerializable{
private String cno;
private String cname;
privateSet<StudentBean> students=new HashSet<StudentBean>();
//省略getter和setter方法
}
在CourseBean.hbm.xml文件中,映射CourseBean类的students属性的代码如下所示:
<set
name="students"
table="study"cascade="save-update">
<key
column="cno"></key>
<many-to-many
class="com.beans.student.StudentBean"column="sno"/>
</set>
<set>元素的table属性指定关系表的名称为Study。
<set>元素的cascade属性为“save-update”,表明保存或更新Course对象时,会级联保存或更新与它关联的Student对象。
<set>元素的<key>子元素指定Study的外键cno,用来参照Course表。
<many-to-many>子元素的class属性指定students集合中存放的是StudentBean的对象,column属性指定Study表的外键sno,用来参照Student表。
经验 对于多对多关联,cascade属性设为“save-update"是合理的,但是不建议把cascade属性设为“all”、“delete"。如果删除一个CourseBean对象时,还级联删除与它关联的所有StudentBean对象,由于这些Student对象有可能还与其他CourseBean对象关联,因此当Hibernate执行级联删除时,会违反数据库的外键参照完整性。
基于以上配置,完成以下持久化操作,创建两个CourseBean对象和两个StudentBean对象,建立它们的关联关系,保存CourseBean对象的同时保存StudentBean对象,如示例1所示。
示例1
下图显示了以上程序建立的CourseBean对象与StudentBean对象的关联关系。
![](http://img.blog.csdn.net/20171129232315610?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd3g1MDQwMjU3/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
当Session的save()方法保存Coursel对象时,向Course表插入一条记录,同时还会分别向Student和Study表插入两条记录,执行如下insert语句:
insert into Course (cname,cno) values (?,?)
insert into Student (sname,sno) values (?,?)
insertinto Student (sname,sno) values (?,?)
insert into Study (cno,sno) values(?,?)
insert into Study (cno,sno) values(?,?)
当Session的save()方法保存course2对象时,向Course表插入一条记录,同时向Study
表插入一条记录。由于与course2对象关联的student1对象已经被保存到数据库中,因此不再向Student表插入记录。Hibernate执行如下SQL语句:
insertinto Course (cname,cno) values (?,?)
insert into Study (cno,sno) values(?,?)
2 配置双向多对多关联
对于双向多对多关联,需要把其中一端的inverse属性设为true,关联的两端都可以使用<set>元素。假定建立了从CourseBean类到StudentBean类的双向多对多关联。在CourseBean类中需要定义集合类型的students属性,并且在StudentBean类也需要定义集合类型的Courses属性。下图显示了CourseBean类和StudentBean类的关联关系。
![](http://img.blog.csdn.net/20171129232557931?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd3g1MDQwMjU3/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
在CourseBean.hbm.xml文件中,映射CourseBean类的students属性的代码如下所示:
<set
name="students"
table="study"cascade="save-update">
<key
column="cno"></key>
<many-to-many
class="com.beans.student.StudentBean"column="sno"/>
</set>
在StudentEntityloyee.hbm.xml文件中,映射Ernployee类的CourseBeans属性的代码如下所示:
<set
name="courses"
table="Study"
inverse="true">
<key
column="sno"></key>
<many-to-many
class="com.beans.student.CourseBean"column="cno"/>
</set>
对于双向多对多关联的两端,需要把其中一端的<set>元素的inverse属性设为“true”。在示例14的基础上,使用双向多对多关联完成持久化操作,同时建立从CourseBean到StudentBean和从StudentBean到CourseBean的关联关系,如示例2所示。
示例2
下图显示了以上程序建立的CourseBean对象与StudentBean对象的关联关系。
![](http://img.blog.csdn.net/20171129232812213?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd3g1MDQwMjU3/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
示例2和示例1的运行结果相似,不再做详细介绍。
经验 在软件开发过程中,根据业务需要,可以把多对多关联分解为两个一对多关联。
具体请参考一下篇博文。
以Course(课程)与Student(学生)类的关系为例,介绍映射多对多关联。一门课程需要多位学生参与,一位学生可能选修多门课程,构成了课程和学生之间的多对多的关系。Course表(课程)、Student表(学生)如图6.4所示。在关系数据模型中,无法直接表达Course表和 Student表之间的多对多关系,需要创建一个连接表Study(学习表)。它同时参照Course表和Student表,下图显示了这3张表的结构。
Study表以sno字段和cno字段作为联合主键。此外,cno字段作为外键参照Course表,而sno字段作为外键参照Student表。
根据业务需要,可以配置课程和学生的单向多对多关联,也可以配置课程和学生的双向多对多关联。接下来详细讲解这两种配置。
1. 配置单向多对多关联
假定仅建立从CourseBean(课程)类到StudentBean(学生)类的单向多对多关联。在CourseBean类中需要定义集合类型students属性,而在StudentBean类中不需要定义集合类型的courses属性。下图显示了CourseBean类和StudentBean类的关联关系。
在CourseBean类中定义students属性代码如下所示:
public class CourseBean implementsSerializable{
private String cno;
private String cname;
privateSet<StudentBean> students=new HashSet<StudentBean>();
//省略getter和setter方法
}
在CourseBean.hbm.xml文件中,映射CourseBean类的students属性的代码如下所示:
<set
name="students"
table="study"cascade="save-update">
<key
column="cno"></key>
<many-to-many
class="com.beans.student.StudentBean"column="sno"/>
</set>
<set>元素的table属性指定关系表的名称为Study。
<set>元素的cascade属性为“save-update”,表明保存或更新Course对象时,会级联保存或更新与它关联的Student对象。
<set>元素的<key>子元素指定Study的外键cno,用来参照Course表。
<many-to-many>子元素的class属性指定students集合中存放的是StudentBean的对象,column属性指定Study表的外键sno,用来参照Student表。
经验 对于多对多关联,cascade属性设为“save-update"是合理的,但是不建议把cascade属性设为“all”、“delete"。如果删除一个CourseBean对象时,还级联删除与它关联的所有StudentBean对象,由于这些Student对象有可能还与其他CourseBean对象关联,因此当Hibernate执行级联删除时,会违反数据库的外键参照完整性。
基于以上配置,完成以下持久化操作,创建两个CourseBean对象和两个StudentBean对象,建立它们的关联关系,保存CourseBean对象的同时保存StudentBean对象,如示例1所示。
示例1
StudentBeanstudent1=new StudentBean(1101,"张三"); StudentBeanstudent2=new StudentBean(1102,"李四"); CourseBeancourse1=new CourseBean(101,"大学物理"); CourseBeancourse2=new CourseBean(102,"计算机基础"); course1.getStudents.add(student1); course1.getStudents.add(student2); course2.getStudents.add(student1); session.save(course1); session.save(course2);
下图显示了以上程序建立的CourseBean对象与StudentBean对象的关联关系。
当Session的save()方法保存Coursel对象时,向Course表插入一条记录,同时还会分别向Student和Study表插入两条记录,执行如下insert语句:
insert into Course (cname,cno) values (?,?)
insert into Student (sname,sno) values (?,?)
insertinto Student (sname,sno) values (?,?)
insert into Study (cno,sno) values(?,?)
insert into Study (cno,sno) values(?,?)
当Session的save()方法保存course2对象时,向Course表插入一条记录,同时向Study
表插入一条记录。由于与course2对象关联的student1对象已经被保存到数据库中,因此不再向Student表插入记录。Hibernate执行如下SQL语句:
insertinto Course (cname,cno) values (?,?)
insert into Study (cno,sno) values(?,?)
2 配置双向多对多关联
对于双向多对多关联,需要把其中一端的inverse属性设为true,关联的两端都可以使用<set>元素。假定建立了从CourseBean类到StudentBean类的双向多对多关联。在CourseBean类中需要定义集合类型的students属性,并且在StudentBean类也需要定义集合类型的Courses属性。下图显示了CourseBean类和StudentBean类的关联关系。
在CourseBean.hbm.xml文件中,映射CourseBean类的students属性的代码如下所示:
<set
name="students"
table="study"cascade="save-update">
<key
column="cno"></key>
<many-to-many
class="com.beans.student.StudentBean"column="sno"/>
</set>
在StudentEntityloyee.hbm.xml文件中,映射Ernployee类的CourseBeans属性的代码如下所示:
<set
name="courses"
table="Study"
inverse="true">
<key
column="sno"></key>
<many-to-many
class="com.beans.student.CourseBean"column="cno"/>
</set>
对于双向多对多关联的两端,需要把其中一端的<set>元素的inverse属性设为“true”。在示例14的基础上,使用双向多对多关联完成持久化操作,同时建立从CourseBean到StudentBean和从StudentBean到CourseBean的关联关系,如示例2所示。
示例2
StudentBeanstudent1=new StudentBean(1101,"张三"); StudentBeanstudent2=new StudentBean(1102,"李四"); CourseBeancourse1=new CourseBean(101,"大学物理"); CourseBeancourse2=new CourseBean(102,"计算机基础"); course1.getStudents.add(student1); course1.getStudents.add(student2); course2.getStudents.add(student1); student1.getCourses().add(course2); session.save(course1); session.save(course2);
下图显示了以上程序建立的CourseBean对象与StudentBean对象的关联关系。
示例2和示例1的运行结果相似,不再做详细介绍。
经验 在软件开发过程中,根据业务需要,可以把多对多关联分解为两个一对多关联。
具体请参考一下篇博文。
相关文章推荐
- hibernate系列七:多对一关联配置及案例
- hibernate系列十:多对多关联配置及案例(二)
- hibernate系列十一:一对一关联配置及案例
- hibernate系列八:一对多关联配置及案例
- Hibernate hbm 外键关联——SSH (Spring+Struts+Hibernate)框架搭建之配置文件序列六
- SpringMVC+Apache Shiro+JPA(hibernate)案例教学(一)整合配置
- Hibernate系列教程之二(SessionFactory配置)
- Hibernate多对多的关联配置
- hibernate.cfg.xml关联Oracle数据库的配置
- Hibernate5:Hibernate框架下的基于注解配置的多表关联的入门级例子(完整版)
- PingingLab传世经典系列《CCNA完全配置宝典》-6.1 项目案例一
- 【转】Hibernate系列学习之(二) 多对一、一对一、一对多、多对多的配置方法
- hibernate多对一关联配置
- hibernate中配置非主键关联(单向一对多)
- 【Hibernate系列】(七):关联映射之一对一
- Spring MVC系列讲座二:与Hibernate的整合开发配置!
- Hibernate入门案例配置以及增、删、改、查看
- Hibernate案例-------基于xml配置,使用Hibernate实现对员工表的增、删、改、查功能
- hibernate中配置非主键关联(单向一对多)
- 屌炸天实战 Mysql 系列教程(一) 生产标准线上环境安装配置案例及棘手问题解决