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中如何来映射这两个的关系呢? 下面就为 ...
随机推荐
- Android Fragment add/replace以及backstack
无论Fragment以何种方式加入,都不会影响backstack,backstack由addToBackStack函数决定,只有调用了这个函数,才会将Fragment加入返回栈.这个说法其实不太准确, ...
- [分享黑科技]纯js突破localstorage存储上线,远程抓取图片,并转码base64保存本地,最终实现整个网站所有静态资源离线到用户手机效果却不依赖浏览器的缓存机制,单页应用最新黑科技
好久没有写博客了,想到2年前答应要放出源代码的也没放出来,最近终于有空先把纯js实现无限空间大小的本地存储的功能开源了,项目地址https://github.com/xueduany/localsto ...
- MooseFS学习-概述
MFS(MooseFS)是一个容错的.网络分布式文件系统,是GFS的开源实现.它把数据分散在多个物理机上,对外展现为一个整体资源. 支持的功能 Unix的通用文件系统功能:目录树:记录POSIX文件属 ...
- python:how does subclass call baseclass's __init__()
First, use baseclass's name to call __init__() I wrote code like this: and we can use 'super' too.
- flex swf和movieclip之前的微妙关系
开始不清楚, 一直尝试想load图片一样加载一个swftools转换的swf,然后在尝试转换成movieclip的时候,总是报错, avmiMovieClip 不能转换成movieclip之类的. 但 ...
- 每天一个linux命令(56):netstat命令
netstat命令用于显示与IP.TCP.UDP和ICMP协议相关的统计数据,一般用于检验本机各端口的网络连接情况.netstat是在内核中访问网络及相关信息的程序,它能提供TCP连接,TCP和UD ...
- Linux内核TCP/IP参数分析与调优
转载于:http://www.itxuexiwang.com/a/liunxjishu/2016/0225/167.html?1456482565 如下图展示的是TCP的三个阶段.1,TCP三次握手. ...
- Atitit 图像金字塔原理与概率 attilax的理解总结qb23
Atitit 图像金字塔原理与概率 attilax的理解总结qb23 1.1. 高斯金字塔 ( Gaussianpyramid): 拉普拉斯金字塔 (Laplacianpyramid):1 1.2 ...
- Atitit dsl实现(1)------异常的库模式实现 异常的ast结构
Atitit dsl实现(1)------异常的库模式实现 异常的ast结构 1.1. Keyword 1 1.2. 异常的ast模型 1 1.3. Astview的jar org.eclipse. ...
- java连接数据库的模糊查询
1:模糊查询是比较常见的一种查询方式,例如在订单表中,包含有订单的具体日期.如果要查询某年某月的订单信息,最好的方式就是使用模糊查询.进行模糊查询需要使用关键字LIKE.在使用LIKE关键字进行模糊查 ...