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) 将多对多查分开来(形成 ...
随机推荐
- for计算位置坐标
代码1效果图: 代码2效果图: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"&g ...
- H5分享到微信好友朋友圈QQ好友QQ空间微博二维码
这是分享按钮: <button onclick="call()">通用分享</button> <button onclick="call(' ...
- java web的安全约束--表单的验证
例子,表单和JDBCRealm的安全验证 参考了一篇文章http://www.cnblogs.com/dyllove98/archive/2013/07/31/3228698.html 1.要在wab ...
- idea打jar包经验总结
关于在idea下打jar问题,在日常工作中经常用到,这里总结下流程. 1.在项目上鼠标右键 --> Open Module Settings 2.如下图,点击 '+' 3. 选择JAR --&g ...
- ORA-07445: exception encountered: core dump [kglpin()+527]
此报错在MOS上查到了相关信息:APPLIES TO: Oracle Database - Enterprise Edition - Version 11.2.0.4 and laterInforma ...
- diskpart分区
分区知识充电: 主分区:主分区,也称为主磁盘分区,和拓展分区.逻辑分区一样,是一种分区类型.主分区中不能再划分其他类型的分区,因此每个主分区都相当于一个逻辑磁(在这一点上主分区和逻辑分区很相似,但主分 ...
- 团队合作之Scrum
CCSU小助手 一:开发团队简介 队名:瓜队 组员:钟文兴.周畅.吉刘磊.唐仲勋 宣言:We are a team at any time! 团队项目描述: 内容:“生活在长大”: 目标:为了方便对学 ...
- C语言 scanf函数
#include <stdio.h> void test1() { // 1.提示用户输入数据 printf("请输入一个整数:"); // 2.接收用户输入的数据 i ...
- 密钥导出函数(Key derivation function)
在密码学中,密钥导出函数(KDF)使用伪随机函数从秘密值(eg.主密钥)导出一个或多个密钥.KDF可用于将密钥扩展到更长的密钥或获得所需格式的密钥(eg.将作为Diffie-Hellman密钥交换的结 ...
- [19/03/24-星期日] 容器_Collection(集合、容器)之List(表,有顺序可重复)
一. 概念&方法 Collection 表示一组对象,它是集中.收集的意思.Collection接口的两个子接口是List.Set接口. 由于List.Set是Collection的子接口,意 ...