hibernate中配置单向多对一关联,和双向一对多,双向多对多
什么是一对多,多对一?
一对多,比如你去找一个父亲的所有孩子,孩子可能有两个,三个甚至四个孩子. 这就是一对多 父亲是1 孩子是多

多对一,比如你到了两个孩子,它们都是有一个共同的父亲. 此时孩子就是多 父亲是1

总结:
- 一对多就是: 1找到n
- 多对一就是: n找到1
有些人写概念写一大堆搞起我之前是一脸懵逼,还好弄懂了(手动滑稽)
双向多对一和双向一对多是不是同一个概念?
是一个概念,双向多对一和双向一对多都是配置一个 一对多和多对一

什么是双向多对多?
可以理解为n找n,如项目可以有很多人做,1个人可以做多个项目.
配置单向多对一
通过上面我们可以了解,双向一对多是 1找n,因为区县有总有很多街道,虽然有的街道没有名字(滑稽),下面我将拿街道和区县举例,实体类的getset我就省略了
//编号
private Integer id;
//街道名称
private String name;
//所属区县编号
private Integer district_Id;
//所属区县
private District district;
因为要找所属区县,所以就增加了一个类类型的变量.
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"E:/codeIdea/hibernate_config/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="cn.pojo.Street" table="street">
<id name="id" column="id" type="java.lang.Integer">
<!--设置主键自动增长就不多说了-->
<generator class="increment"/>
</id>
<property name="name" type="string" column="name"/>
<!--
关联查询District类
name是指Street类中的district属性
column是指district表中外键
class这个就不用多说了 District实体类的路径
cascade的save-update表示 对街道进行添加或更新时会对 县区进行添加或更新
-->
<many-to-one name="district"
column="district_Id"
class="cn.pojo.District"
cascade="save-update"/>
</class>
</hibernate-mapping>
我们来看下配置完后是否可以查询到区县
dao层
public Street findDistrct(Serializable id){
return (Street)HibernateUtil.currentSession().get(Street.class,id);
}
service层
public Street getStreet(Integer id){
Transaction tx=null;
Street streets=null;
try {
tx=HibernateUtil.currentSession().beginTransaction();
//获取持久对象 注意这里没 commit() 因为延迟加载的原因所以没有commit
streets = street.findDistrct(id);
} catch (HibernateException e) {
e.printStackTrace();
if(tx!=null)
tx.rollback();
}
return streets;
}
测试
StreetServiceImpl streetService = new StreetServiceImpl(); System.out.println(streetService.getStreet(1001).getDistrict().getName());
结果:

配置双向一对多
实体类属性 多了一个set因为是 1找n 所以是一个set因为set不允许重复值
//编号
private Integer id;
//区县名称
private String name;
//街道
private Set<Street> streetSet;
双向多对一就是在上面的基础上加了个一对多即成了双向,
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"E:/codeIdea/hibernate_config/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="cn.pojo.District" table="district" schema="scott">
<id name="id" column="id" type="java.lang.Integer">
<!--设置自动增长不多讲了-->
<generator class="increment"/>
</id>
<property name="name" type="string" column="name"/>
<!--
name同上
inverse默认false 是否将对集合对象的修改反映到数据库中 false自己控制,true对方控制
key 是street表中的外键
class同上
-->
<set name="streetSet" inverse="true">
<key column="district_Id"/>
<one-to-many class="cn.pojo.Street"/>
</set>
</class>
</hibernate-mapping>
配置完1找n后我们再来查询下
dao层
public District getDistrct(Integer id){
return (District)HibernateUtil.currentSession().get(District.class,id);
}
service层
public Set<Street> findStreet(Integer id){
Transaction tx=null;
Set<Street> streets=null;
try {
tx=HibernateUtil.currentSession().beginTransaction();
//得到持久状态的对象
District distrct = distrctDao.getDistrct(id);
//得到set
streets=distrct.getStreetSet();
} catch (HibernateException e) {
e.printStackTrace();
if(tx!=null)
tx.rollback();
}
return streets;
}
测试
DistrctServiceImpl ds = new DistrctServiceImpl();
Iterator<Street> streetIter = ds.findStreet(1004).iterator();
while (streetIter.hasNext()){
System.out.println(streetIter.next().getName());
}
数据库的数据

结果
对双向一对读关联进行更新
dao 层
public Street findDistrct(Serializable id){
return (Street)HibernateUtil.currentSession().get(Street.class,id);
}
service层 这里为了快点就没传参了 直接调用即可
public void updateStreet(){
Transaction tx=null;
try {
//打开事务
tx=HibernateUtil.currentSession().beginTransaction();
//获得持久层对象
Street streets = street.findDistrct(1000);
//对区县进行修改
streets.getDistrict().setName("京城");
//提交事务
tx.commit();
} catch (HibernateException e) {
e.printStackTrace();
if(tx!=null)
tx.rollback();
}
}
我们来看看数据库没运行之前

运行之后 可以看到 知春路所属的区县改变了

双向多对多
下面将用项目和员工之间的关系进行配置,因为项目表和员工表需要互相关联,如果两个表直接关联会导致数据有冗余,最重要的是因为相互关联会导致不能删除数据

可以看到这样关联是十分的不好的,这时候我们就可以找一个中间商,进行中转通过它可找到两个表的数据

注意中间商不用建实体类
项目实体类属性如下
//编号
private Integer empId;
//员工名
private String empName;
//开发过的项目
private Set<Project> projects;
项目配置
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"E:/codeIdea/hibernate_config/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="entity.Project" table="project">
<id name="id" column="proid" type="java.lang.Integer">
<generator class="assigned"/>
</id>
<property name="proName" type="string" column="proname"/>
<!-- name是project中的属性名 cascade中的save-update表示 project中对employees集合的更改,添加会保存到数据库-->
<set name="employees" table="proemp" cascade="save-update">
<!-- project所关联的外键-->
<key column="rproId"/>
<!-- column是Employee表关联的外键-->
<many-to-many class="entity.Employee" column="rempId"/>
</set>
</class>
</hibernate-mapping>
员工实体类属性
//编号 private Integer id; //项目名称 private String proName; //工作人员 private Set<Employee> employees;
员工配置
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"E:/codeIdea/hibernate_config/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="entity.Employee" table="employee">
<id name="empId" column="empId" type="java.lang.Integer">
<generator class="increment"/>
</id>
<property name="empName" column="empname"/>
<!-- name是project中的属性名 inverse true表示将控制权给予别人 默认false-->
<set name="projects" table="proemp" inverse="true">
<!--Employee关联的外键-->
<key column="rempId"/>
<!-- column是project表所关联的外键-->
<many-to-many class="entity.Project" column="rproId"/>
</set>
</class>
</hibernate-mapping>
配置完了进行添加如下
dao层
public void add(Project project){
HibernateUtil.currentSession().save(project);
}
service层
public void add(Project project){
Transaction tx=null;
try {
//打开事务
tx=HibernateUtil.currentSession().beginTransaction();
//保存
empDao.add(project);
//提交
tx.commit();
} catch (HibernateException e) {
e.printStackTrace();
if (tx!=null)
//回滚
tx.rollback();
}
}
测试
//创建项目
Project project = new Project(3,"项目3");
//创建员工
Employee employee = new Employee();
Set<Employee> employees = new HashSet<>();
employees.add(employee);
employee.setEmpName("王麻子");
//添加员工 到项目中
project.setEmployees(employees);
//添加项目 保存到数据库
empSerivce.add(project);
没添加之前

运行后

因为控制权给了项目,在员工中进行如上操作对数据库中的项目表并不会进行改动,但是可以查询到如下
dao层
public Employee get(Serializable id){
return (Employee)HibernateUtil.currentSession().get(Employee.class,id);
}
service层
EmpDao empDao =new EmpDao();
public Employee get(Integer id){
Transaction tx = null;
Employee emp = null;
try {
//打开事务
tx=HibernateUtil.currentSession().beginTransaction();
//获取持久化对象
emp = empDao.get(id);
} catch (HibernateException e) {
e.printStackTrace();
}
return emp;
}
测试
EmpSerivce empSerivce = new EmpSerivce();
Employee emp = empSerivce.get(1);
//员工名
System.out.println(emp.getEmpName());
//迭代器
Iterator<Project> iterable = emp.getProjects().iterator();
//遍历 做过的项目
while (iterable.hasNext()){
System.out.println(iterable.next().getProName());
}
结果

工具类代码如下:
package tool;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtil {
private static Configuration configuration;
private static SessionFactory sessionFactory;
//初始化配置和session
static {
try {
//读取配置文件
try {
configuration = new Configuration().configure();
//获取session对象
sessionFactory =configuration.buildSessionFactory();
} catch (HibernateException e) {
e.printStackTrace();
}
} catch (HibernateException e) {
throw new ExceptionInInitializerError();
}
}
private HibernateUtil(){}
//获取session对象
public static Session currentSession(){
return sessionFactory.getCurrentSession();
}
}
hibernate中配置单向多对一关联,和双向一对多,双向多对多的更多相关文章
- Atitit.Hibernate中Criteria 使用总结and 关联查询 and 按照子对象查询 o9o
Atitit.Hibernate中Criteria 使用总结and 关联查询 and 按照子对象查询 o9o 1. Criteria,,Criterion ,, 1 <2. 主要的对象黑头配置磊 ...
- 【Hibernate框架】关联映射(一对多,多对一)
根据我们的总结计划,上篇文章我们总结了有关于一对一映射相关知识,接下来,我们进行下一个阶段,一对多.多对一映射相关知识. 场景设定: 国家规定,一个人只能在一个公司上班,一个公司可以拥有很多员工.我们 ...
- Hibernate 中配置属性详解(hibernate.properties)
Hibernate能在各种不同环境下工作而设计的, 因此存在着大量的配置参数.多数配置参数都 有比较直观的默认值, 并有随 Hibernate一同分发的配置样例hibernate.properties ...
- Hibernate框架--关联映射,一对多,多对多 inverse cascade
回顾Hibernate: 1. hibernate开发环境搭建 ----> 引入jar: hibernate.jar + required + jpa + 驱动包 ---> hiberna ...
- Hibernate系列学习之(二) 多对一、一对一、一对多、多对多的配置方法
这是近期做案件录入.java项目中体会的几点:项目理解很是深刻,和大家共勉! hihernate一对多关联映射(单向Classes----->Student) 一对多关联映射利用了多对一关联映射 ...
- 【转】Hibernate系列学习之(二) 多对一、一对一、一对多、多对多的配置方法
hihernate一对多关联映射(单向Classes----->Student) 一对多关联映射利用了多对一关联映射原理 多对一关联映射:在多的一端加入一个外键指向一的一端,它维护的关系是多指向 ...
- 在Hibernate中配置Hilo进行数据绑定测试时出错:org.hibernate.MappingException: Could not instantiate id generator
在进行学习具体类单表继承时使用hilo类型时总是在调度过程中提示如下信息,无法通过.留下记录备查. 在网上找相关信息, 未解决,详细如下: org.hibernate.MappingException ...
- 详解在Hibernate中配置数据库方言的作用和好处以及各种数据库的方言连接
Hibernate底层依然使用SQL语句来执行数据库操作,虽然所有关系型数据库都支持使用标准SQL语句,但所有数据库都对标准SQL进行了一些扩展,所以在语法细节上存在一些差异,因此Hibernate需 ...
- Hibernate 配置双向多对多关联
本文解决问题:Hibernate 中配置项目(Project) 员工(Employee) 双向多对多关联 方案一:直接配置双向多对多 方案二:配置第三个关联类(xml) 将多对多查分开来(形成 ...
随机推荐
- 9th week -the history of program 1950~2020
We already know that programming language is a formal language designed to communicate instructions ...
- caffe-windows之手写体数字识别例程mnist
caffe-windows之手写体数字识别例程mnist 一.训练测试网络模型 1.准备数据 Caffe不是直接处理原始数据的,而是由预处理程序将原始数据变换存储为LMDB格式,这种方式可以保持较高的 ...
- Tomcat部分操作
一 概述 1.Tomcat是什么? Tomcat是Apache软件基金会提供的开源免费的服务器,适用于中小型系统与并发访问用户不是很多的情况. 2.域名 IP是互联网上一台计算机的唯一标识,但IP不容 ...
- vue+mock.js+element-ui模拟数据搞定分页
效果如图: 前提是搭好vue前端框架,npm install mockjs引入mock.js 当前页全部代码如下,其他有关element-ui的引入未提到,仅作参考用 <!-- 用户管理 --& ...
- javascript实现数据结构与算法系列
1.线性表(Linear list) 线性表--简单示例及线性表的顺序表示和实现 线性表--线性链表(链式存储结构) 线性表的静态单链表存储结构 循环链表与双向链表 功能完整的线性链表 线性链表的例子 ...
- Android 第三方类库简单使用之EventBus
Android 第三方类库之EventBus 1 PS 工欲善其事必先利其器. Eventbus也是一款在开发中常用的利器 这篇也对EventBus的简单介绍和使用,与之前个xutils介绍的级别一样 ...
- Android 笔记之 Android 系统架构
Android笔记之Android系统架构 h2{ color: #4abcde; } a{ color: blue; text-decoration: none; } a:hover{ color: ...
- IntelliJ IDEA搭建SpringBoot的小Demo
首先简单介绍下Spring Boot,来自度娘百科:Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进 ...
- solidity语言6
映射 可以认为是哈希,格式 mapping(_KeyType => _ValueType) pragma solidity ^0.4.0; contract MappingExample { m ...
- ubuntu下go开发环境
https://qiita.com/necomeshi/items/676ccb669d6e6102117b 安装 https://golang.org/dl/ # 下载&解压 axel -n ...