Hibernate框架之双向多对多关系映射
昨天跟大家分享了Hibernate中单向的一对多、单向多对一、双向一对多的映射关系,今天跟大家分享下在Hibernate中双向的多对多的映射关系
这次我们以项目和员工举个栗子,因为大家可以想象得到,在真实的环境下,一个项目肯定是对应着多个员工的,这毫无疑问,
那么同时,一个比较牛员工也能同时参与多个项目的开发,这就体现了双向多对多的关系。
首先呢,我们得弄清楚在底层数据库中表与表之间的关系,我们创建一个员工表(Employee)和项目表(Project)毫无疑问,那么我们要怎么体现出多对多的关系呢?
当然有很多种方法,这里我以单独提出一张关系表为例,也就是说,我单独创建一张表来保存员工和项目的关系,具体的实体类如下
Employee
package entity; import java.util.HashSet;
import java.util.Set; /*
* 员工表
* */
public class Employee {
private Integer empid;//员工编号
private String empname;//员工名称
//准备一个项目集合
private Set<Project> pros=new HashSet<Project>(); public Set<Project> getPros() {
return pros;
}
public void setPros(Set<Project> pros) {
this.pros = pros;
} public Employee(String empname) {
super();
this.empname = empname;
}
public Employee(Integer empid, String empname) {
this.empid = empid;
this.empname = empname;
}
public Employee() {
}
public Integer getEmpid() {
return empid;
}
public void setEmpid(Integer empid) {
this.empid = empid;
}
public String getEmpname() {
return empname;
}
public void setEmpname(String empname) {
this.empname = empname;
} }
Proemp
package entity;
/*
* 表示员工和项目相关联的表
* */
public class Proemp {
private Integer rproid;//项目编号
private Integer rempid;//员工编号 public Proemp(Integer rproid, Integer rempid) {
this.rproid = rproid;
this.rempid = rempid;
}
public Proemp() {
}
public Integer getRproid() {
return rproid;
}
public void setRproid(Integer rproid) {
this.rproid = rproid;
}
public Integer getRempid() {
return rempid;
}
public void setRempid(Integer rempid) {
this.rempid = rempid;
} }
Project
package entity; import java.util.HashSet;
import java.util.Set; /*
* 项目表
* */
public class Project {
private Integer proid;//项目编号
private String proname;//项目名称
//声明员工集合
private Set<Employee> emps=new HashSet<Employee>(); public Set<Employee> getEmps() {
return emps;
}
public void setEmps(Set<Employee> emps) {
this.emps = emps;
} public Project(String proname) {
this.proname = proname;
}
public Integer getProid() {
return proid;
}
public void setProid(Integer proid) {
this.proid = proid;
}
public String getProname() {
return proname;
}
public void setProname(String proname) {
this.proname = proname;
}
public Project(Integer proid, String proname) {
this.proid = proid;
this.proname = proname;
}
public Project() {
}
}
这样我们的实体类就全部创建完毕,接下来我们就可以配置映射关系文件了,既然是双向的多对多的关系,那么肯定少不了<set></set>标签
Project.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="entity">
<class name="Project" table="project">
<id name="proid" column="proid">
<generator class="increment" />
</id>
<property name="proname" type="string" column="proname" />
<!-- 配置多对多的关联关系 设置级联属性-->
<set name="emps" table="proemp" cascade="all">
<key column="rproid"></key>
<many-to-many class="entity.Employee" column="rempid"></many-to-many>
</set>
</class>
</hibernate-mapping>
Employee.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="entity">
<class name="Employee" table="Employee">
<id name="empid" column="empid">
<generator class="increment" />
</id>
<property name="empname" type="string" column="empname" />
<!-- 配置多对多的关联配置 设置反转属性,让项目管理关系 -->
<set name="pros" table="proemp" inverse="true">
<key column="rempid"></key>
<many-to-many class="entity.Project" column="rproid"></many-to-many>
</set>
</class>
</hibernate-mapping>
经过以上的步骤,整个配置过程就全部完成了,当然同学们别忘记了在Hibernate配置文件(大配置)中添加对两个映射文件(小配置)的引用
测试类
package test; import org.hibernate.Session;
import org.hibernate.Transaction; import util.HibernateUtil;
import entity.Employee;
import entity.Project; public class Test {
public static void main(String[] args) {
/*
* 多对多的关联关系配置
* 同时配置了Project和Employee之间双向的多对多的关联关系
* 关联关系由Project方维护,并且在Project方设置了级联属性
* */
//获取Session
Session session=HibernateUtil.currentSession();
//开启事务
Transaction tx = session.beginTransaction();
//构建两个项目
Project pro1=new Project("项目一");
Project pro2=new Project("项目二");
//构建多个员工
Employee emp1=new Employee("巴黎的雨季");
Employee emp2=new Employee("盛夏的果实");
Employee emp3=new Employee("听风");
Employee emp4=new Employee("黎明前的黑暗"); //将员工123加入项目一
pro1.getEmps().add(emp1);
pro1.getEmps().add(emp2);
pro1.getEmps().add(emp3);
//将员工234加入项目二
pro2.getEmps().add(emp2);
pro2.getEmps().add(emp3);
pro2.getEmps().add(emp4); //保存项目一和项目二
session.save(pro1);
session.save(pro2);
//提交事务
tx.commit();
//关闭连接
HibernateUtil.closeSession();
}
}
以上代码,我们可以发现我们仅仅保存了项目,并没有手动的添加保存员工的代码,也没有手动添加保存员工和项目之间关系的表的代码
我们可以看到Hibernate帮我们生成的sql

Hibernate很智能的通过配置文件帮我们生成了我们需要的sql,这就是面向对象思想的体现,我们自始至终都只关注了项目这个对象就完成了我们所需要的操作
我们可以看看数据库中的记录



以上就是如何去配置双向多对多的映射关系的代码和解释了。希望对大家有点用~~
Hibernate框架之双向多对多关系映射的更多相关文章
- Hibernate学习笔记(五) — 多对多关系映射
多对多关系映射 多对多建立关系相当于在第三张表中插入一行数据 多对多解除关系相当于在第三张表中删除一行数据 多对多改动关系相当于在第三张表中先删除后添加 多对多谁维护效率都一样.看需求 在实际开发过程 ...
- Hibernate框架学习之注解配置关系映射
上篇文章我们通过注解对映射了单个实体类,但是具体项目中往往实体类之间又是相互关联的,本篇文章就是从实体类之间存在的不同关联角度,具体学习下如何映射他们之间的关联,主要涉及内容如下: 单向的一 ...
- 深入浅出Hibernate(二)多对一关系映射
学习Hibernate是为了更方便的操作数据库,在数据库中的关系模型中存在多对一的关系,比方下图所看到的的员工和部门之间的关系,那么这样的关系在Hibernate中怎样映射呢?让我用一个小Demo来具 ...
- Hibernate框架学习(七)——多对多关系
一.关系表达 1.表中的表达 2.实体中的表达 3.orm元数据中的表达 在User.hbm.xml中添加: 在Role.hbm.xml中添加(与上相反): 二.操作关联属性 1.保存员工及角色 pu ...
- hibernate学习(设计多对多 关系 映射)
// package org.crazy.app.domain; import java.util.HashSet; import java.util.Set; import javax.persis ...
- HIbernate学习笔记(六) 关系映射之多对多
六.多对多 - 单向 Ø 一般的设计中,多对多关联映射,需要一个中间表 Ø Hibernate会自动生成中间表 Ø Hibernate使用many-to-ma ...
- Hibernate自身一对多和多对多关系映射
一对多关系映射大家都明白,关系双方都一个含有对方多个引用,但自身一对多很多同学都不明白什么意思,那么首先我就说明一下什么是自身一对多,其实也很好理解,自身一对多就是自身含有本身的多个引用,例如新闻类别 ...
- Hibernate多对多关系映射(建表)
下边讲述Hibernate多对多关系映射. 多对多关系的表的结构为: 两个实体表,还包含一个关系表,关系表为复合主键,如果要使用Hibernate多对多关系映射,则关系表必须只包含两个字段,如果生成了 ...
- 菜鸟学习Hibernate——多对多关系映射
Hibernate中的关系映射,最常见的关系映射之一就是多对多关系映射例如用户与角色的关系,一个用户对应多个角色,一个角色对应多个用户.如图: Hibernate中如何来映射这两个的关系呢? 下面就为 ...
随机推荐
- 七步,搭建基于Windows平台完美Jekyll博客环境
最近,基于Jekyll新搭建了自己英文博客.整个过程搜索了不少资料,也尝试和过滤了不少工具和插件,最后的效果还是不错的.这里总结一下主要的七个步骤,感兴趣的朋友可以参考一下: 第一步,安装Ruby开发 ...
- MFC:在OnInitDialog 里面关闭窗体
解决步骤 在对应的dialogcpp 文件里面的在OnInitDialog函数里面,找到对应的位置,您需要结束窗体显示的地方.(感觉这是废话) 经过验证,使用EndDialog(IDCANCEL);/ ...
- IOS 推送-客户端处理推送消息
IOS 推送-客户端处理推送消息 1.推送调用顺序 APN push的消息到达后,UIApplicationDelegate有两个方法和处理消息有关: 1)application:didReceive ...
- Java-条件语句、循环语句练习
题目一:一张纸的厚度大约是0.08mm,对折多少次之后能达到珠穆朗玛峰的高度(8848.13米)? double height=0.08; for(int i=1;i>0;i++) { heig ...
- NodeJS实例系列~环境搭建,Hello world归来!
回到目录 1 安装Node.js服务端程序 https://github.com/Microsoft/nodejstools/wiki/Install-Node.js-and-get-started- ...
- Atitit 跨平台异常处理(2)--------异常转换 -----java c# js异常对象结构比较and转换
Atitit 跨平台异常处理(2)--------异常转换 -----java c# js异常对象结构比较and转换 { "@type":"java.lang.Runti ...
- paip.为什么使用多线程的原因.
paip.为什么使用多线程的原因. 作者Attilax 艾龙, EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:http://blog.csdn.net/att ...
- fir.im Weekly - 从零开始,搭建理想的直播平台
2016年苹果发布会如期而至,新一代的 iPhone 7, Apple Watch 同时亮相,可惜大家期待的 MacBookPro.AR.VR产品并未出现.不论大家对新产品是"买买买&quo ...
- Jenkins+MSbuild+SVN实现dotnet持续集成 快速搭建持续集成环境
Jenkins是一个可扩展的持续集成引擎,Jenkins非常易于安装和配置,简单易用,下面开始搭建dotnet持续集成环境 一.准备工作 1.系统管理-->管理插件-->可选插件中找到MS ...
- 学习ASP.NET MVC(九)——“Code First Migrations ”工具使用示例
在上一篇文章中,我们学习了如何使用实体框架的“Code First Migrations ”工具,使用其中的“迁移”功能对模型类进行一些修改,同时同步更新对应数据库的表结构. 在本文章中,我们将使用“ ...