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中如何来映射这两个的关系呢? 下面就为 ...
随机推荐
- C#入门基础二
万物皆对象:对象是包含数据和操作的实体. 属性:名词 / 对象 \ 方法:动词 ============================================== ...
- Linux创建用户(转)
这篇文章总结的太好了,让我没动力新写一篇了,啊哈哈哈哈. 源自:http://www.cnblogs.com/ylan2009/articles/2321177.html Linux 系统是一个多用户 ...
- Linux 容器技术史话:从 chroot 到未来
Linux 容器是一个在单一 Linux 主机上提供多个隔离的 Linux 环境的操作系统级虚拟技术.不像虚拟机(VM),容器并不需要运行专用的访客(guest)操作系统.容器们共享宿主机的(host ...
- CAR
24.编写一个Car类,具有String类型的属性品牌,具有功能drive: 定义其子类Aodi和Benchi,具有属性:价格.型号:具有功能:变速: 定义主类E,在其main方法中分别创建Aodi和 ...
- [Spring框架]Spring 事务管理基础入门总结.
前言:在之前的博客中已经说过了数据库的事务, 不过那里面更多的是说明事务的一些锁机制, 今天来说一下Spring管理事务的一些基础知识. 之前的文章: [数据库事务与锁]详解一: 彻底理解数据库事务一 ...
- Atitit 马尔可夫过程(Markov process) hmm隐马尔科夫。 马尔可夫链,的原理attilax总结
Atitit 马尔可夫过程(Markov process) hmm隐马尔科夫. 马尔可夫链,的原理attilax总结 1. 马尔可夫过程1 1.1. 马尔科夫的应用 生成一篇"看起来像文章的 ...
- Atitit 图像清晰度 模糊度 检测 识别 评价算法 源码实现attilax总结
Atitit 图像清晰度 模糊度 检测 识别 评价算法 源码实现attilax总结 1.1. 原理,主要使用像素模糊后的差别会变小1 1.2. 具体流程1 1.3. 提升性能 可以使用采样法即可..1 ...
- Atitit 信用卡与会员卡(包括银行卡)的发展之路
Atitit 信用卡与会员卡(包括银行卡)的发展之路 实现跨机构卡片内金额的流动解决方案 1.1. 财务卡片本质上都是会员卡1 1.2. 卡片的发展阶段1 2. 实现跨机构卡片内金额的流动解决方案(加 ...
- 【译】怎样编写移动优先的CSS
原文:How To Write Mobile-first CSS 作者: 译者:huansky 构建响应式网站是今天前端开发人员必备的技能. 当我们谈论响应式网站时,移动优先这个词立刻就会浮现. 我们 ...
- javaweb回顾第十一篇过滤器(附实现中文乱码问题)
1:过滤器概念 过滤器就是一种在请求目标资源的中间组件,比喻把污水转换成纯净水中间需要一个污水净化设备,那么这个设备就好比一个过滤器.那么我用图来表示过滤器(可以有多个过滤器)运行的过程 2:Filt ...