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中如何来映射这两个的关系呢? 下面就为 ...
随机推荐
- [ACM_动态规划] 最长上升子序列(LIS)
问题描述:给n个数,找出最长子序列并输出 问题分析:本题是DAG(有向无环图)最长路问题,设d[i]为以i结尾的最长链的长度,则状态转移方程为:d[i]=max{0,d[j]|j<i & ...
- AWS系列之三 使用EBS
Amazon Elastic Block Store(EBS)可作为EC2实例的持久性数据块级存储.其具有高可用性和持久性的特点,可用性高达99.999%.给现有的EC2实例扩展新的存储块只需要几分钟 ...
- ASP.NET集成模式下的管道事件
- IOS Animation-CABasicAnimation、CAKeyframeAnimation详解&区别&联系
1.先看看网上流传的他们的继承图: 从上面可以看出CABasicAnimation与CAKeyframeAnimation都继承于CAPropertyAnimation.而CAPropertyAnim ...
- XMPie Tracking 操作
XMPie Tracking 操作 1.1 打开页面 我们随便打开一个页面,这里打开landing.aspx 我们想要跟踪页面,选中DW上面的TrackingàTracking Page Vis ...
- Java基础之常用类
1.Collections类: (1)此类完全由在 collection 上进行操作或返回 collection 的静态方法组成. (2)静态方法摘要: static <T> boolea ...
- Oracle建表脚本记录
--删除 drop table dianfei; --创建表 create table dianfei ( uon ) not null, mmonth ) not null, ddf ,) not ...
- 破解Excel密码保护文件
首先打开vba编辑器,输入代码: Public Sub AllInternalPasswords() ' Breaks worksheet and workbook structure passwor ...
- 阿里云配置mysql navcat远程连接
默认是不能用客户端远程连接的,阿里云提供的help.docx里面做了设置说明,mysql密码默认存放在/alidata/account.log 首先登录: mysql -u root -h local ...
- 每天一个linux命令(37):date命令
在linux环境中,不管是编程还是其他维护,时间是必不可少的,也经常会用到时间的运算,熟练运用date命令来表示自己想要表示的时间,肯定可以给自己的工作带来诸多方便. 1.命令格式: date [参数 ...