Hibernate(V)——一对多与多对多关联关系映射(xml与注解)总结
Hibernate关系映射笔记

2015年10月12日Hibernate笔记----Day4映射文件总结:(多对一、一对多、一对一、多对多)多对一:新建项目---引包---加包1、编写Java类,指明属性,生成get和set方法1)将n的一端类名属性加到1的一端。
2)1的一端无变化。
2、生成配置文件*.hbm.xml1)选中Java文件右键---new----other----"输入Hibernate"---选择Hibernate XML Maping2) 改:generator class="native"3)1的一端无变化,n的一端加入many-to-one如:<many-to-one name="customer"class="qjnu.wdw.day3.Customer"><column name="CUSTOMER_RK" /></many-to-one>(其中,name 必须与Customer.java中属性一致)3、添加关联的hibernate 映射文件*.hbm.xml如:<mapping resource="qjnu/wdw/day3/Customer.hbm.xml"/>4、测试类中先保存1的一端,再保存n的一端。
一对多:新建项目---引包---加包1、编写Java类,指明属性,生成get和set方法1)将n的一端类名属性加到1的一端。
2)1的一端加入n端的集合属性。
例如:private Set<Order> orders = new HashSet<>();2、生成配置文件*.hbm.xml1)选中Java文件右键---new----other----"输入Hibernate"---选择Hibernate XML Maping2) 改:generator class="native"3)1的一端加入one-to-many如:<set name="orders" table="ORDERS" inverse="true" cascade="all"> <key column="CUSTOMER"></key><one-to-many qjnu.wdw.day3.Order/></set>(其中,name 属性保持一致)n的一端加入many-to-one如:<many-to-one name="customer" class="qjnu.wdw.day3.Customer" ><column name="CUSTOMER" /></many-to-one>3、添加关联的hibernate 映射文件*.hbm.xml如:<mapping resource="qjnu/wdw/day3/Customer.hbm.xml"/>4、测试类中先保存1的一端,再保存n的一端。
Hibernate(6)—— 一对多和多对多关联关系映射(xml和注解)总结

Hibernate(6)——一对多和多对多关联关系映射(xml和注解)总结涉及的知识点总结如下:∙One to Many 映射关系o多对一单向外键关联(XML/Annotation)o一对多单向外键关联(XML/Annotation)o懒加载和积极加载o一对多双向外键关联(XML/Annotation)∙Many to Many 映射关系o多对多单向外键关联(XML/Annotation)o多对多双向外键关联(XML/Annotation)o set的inverse元素详解∙问题小结∙关联关系的优缺点多对一单向外键关联关系注意多对一关联是多方持有一方的引用。
看一个例子,去淘宝购物,那么一个淘宝用户可以对应多个购物订单,如图所示:多的一方是Orders,持有一方的引用,也就是Users,而在Users中无需作任何定义,从订单到用户的关系是单向多对一关联。
对应数据库就是:还有比如说学生和班级的关系,多个学生可以属于同一个班级,这就是从学生到班级也是典型的单向多对一关系,看代码实现:基于注解的多对一单向外键关联:单向多对一关联中,多方需要持有一方的引用,那么多方(学生类)需要额外配置,需要对持有的一方引用使用注解@ManyToOne (cascade={CascadeType.ALL}, fetch=FetchType.EAGER),设置为级联操作和饥渴的抓取策略,@JoinColumn(name="cid"),而一方(教室类)无需做任何多方的定义。
注意;多方必须保留一个不带参数的构造器!importjavax.persistence.Entity;importjavax.persistence.GeneratedValue;importjavax.persistence.Id;//班级类,在多对一关系中属于一的方,不持有其他多余的配置,反而是被多方持有@Entitypublic class ClassRoom {private intcid;//班级编号private String cname;//班级名称// 自动增长的主键@Id@GeneratedValuepublicintgetCid() {returncid;}public void setCid(intcid) {this.cid = cid;}public String getCname() {returncname;}public void setCname(String cname) {ame = cname;}}View Code一方——班级类无需做多余的定义,下面是多方——学生实体和配置:importjavax.persistence.CascadeType;importjavax.persistence.Entity;importjavax.persistence.FetchType;importjavax.persistence.GeneratedValue;importjavax.persistence.Id;importjavax.persistence.JoinColumn;importjavax.persistence.ManyToOne;//学生实体类,属于多对一的多方,持有班级(一方)的引用@Entitypublic class Students {private intsid; //编号private String sname; //姓名private ClassRoom classroom;//学生班级//注意:多方一定要显式的定义不带参数的构造方法public Students() {}public Students(String sname){this.sname = sname;}// 多方使用注解:@ManyToOne// fetch=FetchType.EAGER,急加载,加载一个实体时,定义急加载的属性会立即从数据库中加载。
Hibernate关联映射(多对一和一对多)

共性问题集中讲解
常见问题及解决办法 代码规范问题 调试技巧
共性问题集中讲解
映射一对一关联关系的方法:
按照外键映射 按照主键映射。
Session管理缓存的方法:
evict() clear()方法。
批量处理的方法:
通过HQL进行批量操作 通过JDBC API进行批量操作 通过Session进行批量操作。
提示:
需要搭建openSessionInView模式 按步骤配置二级缓存和查询缓存
完成时间:20分钟
共性问题集中讲解
常见问题及解决办法 代码规范问题 调试技巧
共性问题集中讲解
HQL的连接查询
和SQL查询一样,HQL也支持各种各样的连接 查询,如内连接、外连接。
连接类型 内连接 迫切内连接 左外连接 迫切左外连接 右外连接
<generator class="afosrseigignne"d>" />
</id><param name="property">resume2</param>
<p<ro/gpeenrteyrantaomr>e="resname" type="ng.String">
</<idc>olumn name="RESNAME" length="40">
<p<rocopleurmtynnnaammee==""uRseESrnCaAmRDe"NtOy"pele=n"gjathva=."l4an0"g>.String">
Hibernate_关联关系(多对一和一对多)理论

关联关系
类与类之间最普遍的关系就是关联关系
单向的关联 双向的关联
6/29
多对一单向关联关系
配置从Emp到Dept的多对一单向关联
Dept持久化类 Emp持久化类
Dept.hbm.xml
Emp.hbm.xml
<clapsusbnlicamclea=s"scDn.ejbpitt.ihmibpelermnaetnetdseSmeor.ieanlitziatyb.lDEeme{ppt" table="edmeppt"">> <pidrivnaatme eB=y"tdeemedppetNpotN"oc;olumn="EDMEPTNNOO" "tytpypee=="j"ajavava.l.alanngg.I.nBteygtee"r>"> pr<igvaetneeSrattroinrgcldaespst=N"aamssei;gned"/> <p/irdiv>ate String location;
13/29
共性问题集中讲解
常见问题及解决办法 代码规范问题 调试技巧
共性问题集中讲解
14/29
学员操作——配置一对多双向关联
需求说明
配置区县到街道的双向的一对多 添加区县级联添加该区县下的两个街道 设置区县的inverse属性值为true,修改某区县, 从该区县中移走某一街道。 设置区县的<set>元素的order-by属性为:按照街 道编号倒叙排序
更新所有关联的游离状态的对象。
delete
当通过Session的delete()方法删除当前对象时,会 级联删除所有关联的对象。
hibernate之映射文件VS映射注解

hibernate之映射⽂件VS映射注解前⾔ 对于java开发者⽽⾔,注解应该不是⼀个陌⽣的概念,早在JavaSE阶段,例如@Override标记重写⽗类⽅法或实现接⼝⽅法,@Test标记单元测试⽅法,所以我们可以简单地把它理解为⼀种有特殊含义的标记...在开发过程中,我们还可以⽤注解⽅式替代配置⽂件实现相关功能,例如Java web开发中,3.0版本后,利⽤@WebServlet、@WebListener等注解分别可以替代web项⽬XML配置⽂件中相关内容。
⽽本⽂中讲述的就是Hibernate的映射配置⽂件与映射注解的对⽐,这两种⽅式均可以实现映射功能,为了避免先⼊为主,在此先不阐述孰优孰劣,接下来以实体类基本映射⽰例,分别⽤配置⽂件和注解⽅式实现。
hibernate.cfg.xml配置⽂件在使⽤两种⽅式时的变动<?xml version="1.0"?><!DOCTYPE hibernate-configuration PUBLIC"-//Hibernate/Hibernate Configuration DTD 3.0//EN""/dtd/hibernate-configuration-3.0.dtd"><hibernate-configuration><session-factory><!-- 以下四⾏分别为:数据库驱动类、Drivermanager获取连接的参数URL、⽤户名、密码 --><property name="connection.driver_class">com.mysql.jdbc.Driver</property><property name="connection.url">jdbc:mysql://127.0.0.1/web?characterEcoding=utf-8</property><property name="ername">root</property><property name="connection.password">123456</property><!-- 设置⽅⾔,hibernate会根据数据库的类型相应⽣成SQL语句 --><property name="dialect">org.hibernate.dialect.MySQLDialect</property><!-- 1.使⽤映射⽂件时 --><!-- 映射配置源⽂件的位置 --><mapping resource="demo/pojo/Person.hbm.xml"/><!-- 2.使⽤映射注解时 --><!-- 注册关系映射类 --><mapping class="demo.pojo.Person" /></session-factory></hibernate-configuration>实体类映射背景:数据库中⼀个⽤户表person,字段四个,包涵⾃增主键id、姓名name、性别sex、年龄age,映射实体类为Person,属性四个,id、name、gender、age。
hibernate核心,一对多,多对多映射讲解,看了就完全搞明白了

在many一方删除数据1
• 删除“五四大道”
inverse设为true,由many一方删除 从one一方去“删除”, Hibernate只是执行了 问题出在配置文件上 update语句。还是未删 没有配置set节点的inverse属性 除成功! 根本没有执行 Delete语句,数据 没有被删除!
– 配置Hibernate多对多关联,实现某OA系统项 目和人员对照关系的管理
本章目标
• 掌握单向many-to-one关联 • 掌握双向one-to-many关联 • 掌握many-to-many关联
实体间的关联
• 单向多对一
tblJd.getQx().getQxname();
• 单向一对多
TblJd jd = (TblJd)tblQx.getJds().get(0); jd.getJdname(); tblQx.getJds.add(jd);
小结
• 在租房系统中,房屋信息(Fwxx)与用户 (User)间也是多对一关系。如何配置映 射文件,使之可以通过下面的代码输出房 屋信息和发布该信息的用户名称? Fwxx fwxx = (Fwxx)super.get(Fwxx.class,1);
System.out.println( fwxx.getTitle() + "," + fwxx.getUser.getUname());
inverse是“反转”的意思,表示关联关系的控制权。 为true,表示由对方负责关联关系的添加和删除; 执行了delete语句, 为false,表示由自己负责维护关联关系。 删除成功
• 在many一方删除数据的正确做法:
Hibernate注解(一对一、一对多、多对多)

Hibernate注解(⼀对⼀、⼀对多、多对多)JPA(Java Persistence API)通过注解或XML描述对象与关系表的映射关系,并将运⾏期的实体对象持久化到数据库中。
JPA是⼀个规范,是⼀个标准,Hibernate是实现了这个标准的开源框架。
1、引⼊hibernate-jpa-2.0-api-1.0.0.Final.jar JPA规范对应的hibernate的jar包2、修改配置⽂件hibernate.cfg.xml 的映射关系<Mapping class=""><?xml version="1.0" encoding="utf-8"?><!DOCTYPE hibernate-configurationPUBLIC "-//Hibernate/Hibernate Configuration DTD//EN""/hibernate-configuration-3.0.dtd"><hibernate-configuration><session-factory><!-- thread:⼀个线程中使⽤⼀个。
获取session会话时使⽤--><property name="current_session_context_class">thread</property><!-- 是否显⽰SQL语句,值为布尔型,默认false --><property name="hibernate.show_sql">true</property><!-- 是否格式化显⽰sql语句,让显⽰更美观,值为布尔型,默认false --><property name="hibernate.format_sql">false </property><!-- ⾃动建表update:每次执⾏时,⽆表则建表,⽆列则建列,只增不减create:每次启动的时候,删除原表,再次创建create-drop:每次启动时创建新表,当显式关闭sessionFactory时,删除表--><property name="hibernate.hbm2ddl.auto">update</property><!-- 连接数据库 --><property name="hibernate.connection.url">jdbc:mysql://127.0.0.1:3306/zxd_db</property><property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property><property name="ername">zxd</property><property name="hibernate.connection.password">123456</property><property name="dialect">org.hibernate.dialect.MySQLDialect</property><!-- 读取注解 --><mapping class="demo.entity.Book"/></session-factory></hibernate-configuration>3、实体配置package demo.entity;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.Table;import org.hibernate.annotations.GenericGenerator;/*** 注解实体配置* JPA通过注解或XML描述对象与关系表的映射关系,并将运⾏期的实体对象持久化到数据库中。
Hibernate一对多、一对一、多对多映射之xml篇

一、一对多/多对一1.确定谁是一方,谁是多方。
某表的主键在另一表中为外键,则某表为一方。
如学生和班级的对应关系,一个班级对应多个学生,所以班级为一方,学生为多方。
2.一方和多方po中部分代码的书写ClassInfo一方:set<多方类型> 的属性代码如:private Set<Student> stuSet;Student多方:一方类型的属性注意:不写外键字段。
代码如:private ClassInfo classInfo;3、配置ClassInfo一方:<set name="student" > 子元素:<key column="哪个字段是别人的外键(class_id)" /> <one-to-many class=”Student”></set>Student多方:<many-to-one name="classInfo" class="ClassInfo"column="class_id" >4、测试添加记录时的dao一部分代码ClassInfo c=new ClassInfo();c.setCname("aaa");Student s=new Student();s.setStuName("gsc");s.setAge(12);s.setEmail("gsc@");Set<Student> stuSet=new HashSet<Student>();stuSet.add(s);c.setStuSet(stuSet);Session session = HibUtil.getSession();Transaction tx = session.beginTransaction();session.save(c);mit();session.close();二一对一1.外键关联:一对多的基础上在外键字段上加个唯一约束构成1对1的关系。
hibernate关系映射总结

5.2.2.3、一对一主键关系映射(非延迟抓取) 配置 1(UserModel.hbm.xml) Java 代码 1. <one-to-one name="userGeneral" cascade="all"/>
配置 2(UserGeneralModel.hbm.xml) Java 代码 1. 2. 3. 4. 5. 6. 7. 8. 关联的对象所对应的数据库表之间,通过一个外键引用对主键进行约束。 <id name="uuid"> <generator class="foreign"> <param name="property">user</param> </generator> </id> <one-to-one name="user" class="erModel"/>
四、如何把数据库关系表示为面向对象中的关系: 1、关联:将数据库表之间的关系转化为对象之间的关系;在 Hibernate 中总指实体之间的关系。 2、映射:完成 java 对象到数据库表的双向转换。 3、级联(可选):将数据库中的级联转化为对象中的级联(两者(对象和数据库表)没关系)。 4、Hibernate 的表和对象的映射: 1、实体类型映射: 4.1.1、主键之间的映射
5.2.2、实体关联关系映射: 5.2.2.1、单向关联关系映射,不演示。 5.2.2.2、双向关联关系映射
Java 代码 1. 2. 3. 4. 5. 6. 单向 定义:不知道另一端什么情况,获取一端另一端自动获取,因为单向,你不知道另一侧是什么。 如 class A{ B b;} class B{ } 只能从 A 导航到 B,不能从 B 导航到 A 关系维护:另一端维护,如 B 维护
hibernate最精细总结 java

Hibernate总结注:重点讲解关联映射总结人:张焕邮箱:zhang343489603@欢迎交流讨论。
目录1)核心接口简介2)Hibernate版本更新情况3)Hibernate关联映射4)简单属性查询5)Hibernate与延迟加载6)hibernate 中Criteria 的使用介绍7) Hibernate程序性能优化Hibernate优点:1、封装了jdbc,简化了很多重复性代码。
2、简化了DAO层编码工作,使开发更对象化了。
3、移植性好,支持各种数据库,如果换个数据库只要在配置文件中变换配置就可以了,不用改变hibernate代码。
4、支持透明持久化,因为hibernate操作的是纯粹的(pojo)java类,没有实现任何接口,没有侵入性。
所以说它是一个轻量级框架。
Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。
Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web 应用中使用,最具革命意义的是,Hibernate可以在应用EJB的J2EE架构中取代CMP,完成数据持久化的重任。
1)核心接口简介:Hibernate的核心接口一共有6个,分别为:Session、SessionFactory、Transaction、Query、Criteria和Configuration。
这6个核心接口在任何开发中都会用到。
通过这些接口,不仅可以对持久化对象进行存取,还能够进行事务控制。
下面对这6个核心接口分别加以介绍。
Session接口Session接口负责执行被持久化对象的CRUD操作(CRUD的任务是完成与数据库的交流,包含了很多常见的SQL语句。
)。
但需要注意的是Session对象是非线程安全的。
同时,Hibernate的session不同于JSP应用中的HttpSession。
Hibernate一对多,多对多,多对一检索策略

Hibernate⼀对多,多对多,多对⼀检索策略⼀.概述我们先来谈谈检索数据时的两个问题:1.不浪费内存2.更好的检索效率以上说的问题都是我们想要避免的,接下来就引出了我们要讨论的话题---------------hibernate检索策略⼆.hibernate检索策略分为三种:1.类级别的检索策略2.⼀对多和多对多检索策略3.多对⼀和⼀对⼀关联的检索策略(1)类级别的检索策略分为⽴即检索和延迟检索,默认为延迟检索。
⽴即检索:⽴即加载检索⽅法指定的对象,⽴即发送SQL.延迟检索:延迟加载检索⽅法指定的对象,在使⽤具体的对象时,再进⾏加载,发送SQL.lazy有两个取值:false(⽴即加载)和 true(延迟加载)讨论⼀:当⽤get()⽅法检索数据时,在类级别检索策略不管是不是延迟加载都会⽴即检索接下来看看代码实现是不是跟我说的⼀样:配置⽂件中:测试类代码:@Testpublic void select1(){Session session = HibernateUtil.currentSession();Transaction tx = session.beginTransaction();House house = session.get(House.class, 1);System.out.println("===========================");// System.out.println(house.getType().getName());mit();HibernateUtil.closeSession();}接下来看看测试的效果:接下来我们把lazy设为true:效果:⼤家注意没,测试类有⼀⾏代码我是注释掉的,为的就是让我们很好的理解,如果我把下⾯的代码放开是什么效果呢?⼤家要注意现在我们的查询是get()⽅法:我们得到的结果是⼀样的,这样就说明了当使⽤类级别检索时,使⽤get()⽅法都会⽴即加载。
hibernate多对一、一对一、一对多、多对多的配置方法

注意:inverse属性,只影响数据的存储,也就是持久化
inverse和cascade
* inverse是关联关系的控制方向
* cascade操作上的连锁反应
hibernate一对一主键关联映射(单向关联Person---->IdCard)
一对一主键关联映射:让两个实体对象的id保持相同,这样可以避免多余的字段被创建
hihernate一对多关联映射(单向Classes----->Student多的一端加入一个外键指向一的一端,它维护的关系是多指向一
一对多关联映射:在多的一端加入一个外键指向一的一端,它维护的关系是一指向多
也就是说一对多和多对一的映射策略是一样的,只是站的角度不同
默认根据主键加载
hibernate一对一唯一外键关联映射(单向关联Person---->IdCard)
一对唯一外键关联映射是多对一关联映射的特例
可以采用<many-to-one>标签,指定多的一端的unique=true,这样就限制了多的一端的多重性为一
通过这种手段映射一对一唯一外键关联
<one-to-one name="idCard" constrained="true"/>
hibernate一对一主键关联映射(双向关联Person<---->IdCard)
需要在idcard映射文件中加入<one-to-one>标签指向person,指示hibernate如何加载person
</set>
table属性值必须和单向关联中的table属性值一致
<key>中column属性值要与单向关联中的<many-to-many>标签中的column属性值一致
Hibernate知识点总结

日期作业: 2011年12月8日Hibernate课堂讲课知识点总结:一.hibernate基础知识二.hibernate一对一映射三.hibernate一对多(多对一)映射四.hibernate多对多映射五.hibernate的HQL检索学习一.Hibernate基础知识1.hibernate:hibernate就是一个可以自动的根据xml或annotation完成对象关系映射(orm),并持久化到数据库的开源框架。
是连接java应用程序和关系数据库的中间件,这是对JDBC的封装,主要负责java对象的持久化。
2.ORM(Object Relation Mapping)对象关系映射是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。
3.hibernate映射文件:它的作用是描述持久层对象以及让他们的属性和数据库中的表和表的字段之间的对应关系。
没有映射文件,Hibernate系统无法完成Java对象和数据库表中的数据的相互转化。
只有通过映射文件,Hibernate才能知道所操作的对象与哪个表相关联。
4.hibernate.cfg.xml文件中包含了hibernate与数据库的基本连接信息。
在Hibernate工作的初始阶段,由Configuration的对象开启hibernate框架,然后将信息加载到SessionFactory实例中。
5.SessionFactory是Hibernate中的一个类,这个类主要负责保存Hibernate的配置信息,以及对Session的操作。
6.手动创建hibernate框架的步骤:a)拷贝所需Jar包到lib目录下,基本包含(antlr.jar,cglib.jsr,asm.jar,commons-collections.jar,commons-logging.jar,jta.jar,dom4j.jar,hibernate3.jar,hibernate-annotations.jar)b)在src目录下创建一个hibernate.cfg.xml文件,该文件包含了hibernate与数据库连接的基本连接信息。
Hibernate用注解方式实现一对多、多对多关系

Hibernate⽤注解⽅式实现⼀对多、多对多关系⼀、⼀对多关系 1、在上⼀篇⽇志中⽤.xml配置⽂件项⽬基础上,再往lib⽬录先添加⼀个包-hibernate-jpa-2.0-api-1.0.0.Final.jar 2、新建⼀个com.st.bean4 包,往包⾥⾯添加两个含有注解的类: a)、DeptBean2类:1 package com.st.bean4;23 import java.util.HashSet;4 import java.util.Set;567 import javax.persistence.Column;8 import javax.persistence.Entity;9 import javax.persistence.GeneratedValue;10 import javax.persistence.Id;11 import javax.persistence.JoinColumn;12 import javax.persistence.OneToMany;13 import javax.persistence.Table;1415 import org.hibernate.annotations.Cascade;16 import org.hibernate.annotations.CascadeType;17 import org.hibernate.annotations.GenericGenerator;1819 @Entity //指定实体类20 @Table(name="DEPT") //对应表的名称21 @GenericGenerator(name="genID", strategy="increment") //声明主键⽣成策略22 public class DeptBean2 {23 @Id //指定主键24 @GeneratedValue(generator="genID") //设定主键⽣成策略25 @Column(name="ID") //指定类中的属性与表中的列的对应关系26 private long id;27 @Column(name="NAME") //指定类中的属性与表中的列的对应关系28 private String name;2930 @OneToMany //指定⼀对多关系31 @Cascade(value={CascadeType.SAVE_UPDATE}) //设定级联关系32 @JoinColumn(name="dept_id") //指定与本类主键所对应的外表的外键33 private Set<EmployeeBean2> emp = new HashSet<EmployeeBean2>();34 @Override35 public String toString() {36 return "DeptBean [id=" + id + ", name=" + name +"]";37 }38 public long getId() {39 return id;40 }41 public void setId(long id) {42 this.id = id;43 }44 public String getName() {45 return name;46 }47 public void setName(String name) {48 = name;49 }50 public Set<EmployeeBean2> getEmp() {51 return emp;52 }53 public void setEmp(Set<EmployeeBean2> emp) {54 this.emp = emp;55 }56 } b)、EmployeeBean类:1 package com.st.bean4;23 import javax.persistence.Column;4 import javax.persistence.Entity;5 import javax.persistence.GeneratedValue;6 import javax.persistence.Id;7 import javax.persistence.JoinColumn;8 import javax.persistence.ManyToOne;9 import javax.persistence.Table;11 import org.hibernate.annotations.GenericGenerator;1213 @Entity //指定⼀个实体14 @Table(name="employee") //指定表的名称15 @GenericGenerator(name="genID", strategy="increment") //声明主键⽣成策略16 public class EmployeeBean2 {17 @Id //指定主键18 @GeneratedValue(generator="genID") //设定主键⽣成策略19 @Column(name="ID") //类中的属性和表中的列名的对应关系20 private long id;21 @Column(name="NAME")22 private String name;23 @Column(name="SEX")24 private String sex;25 @Column(name="JOB")26 private String job;27 @ManyToOne// 指定多对⼀关系 //指定多对⼀关系28 @JoinColumn(name="DEPT_ID")29 //⼀个员⼯对应于⼀个部门号,所以这⾥不⽤集合30 private DeptBean2 dept ; //注意这个地⽅不要new对象,否则会⽆法运⾏31 public long getId() {32 return id;33 }34 public void setId(long id) {35 this.id = id;36 }37 public String getName() {38 return name;39 }40 public void setName(String name) {41 = name;42 }43 public String getSex() {44 return sex;45 }46 public void setSex(String sex) {47 this.sex = sex;48 }49 public String getJob() {50 return job;51 }52 public void setJob(String job) {53 this.job = job;54 }55 public DeptBean2 getDept() {56 return dept;57 }58 public void setDept(DeptBean2 dept) {59 this.dept = dept;60 }61 @Override62 public String toString() {63 return "EmployeeBean [id=" + id + ", name=" + name + ", sex=" + sex64 + ", job=" + job + ", dept=" + dept65 + "]";66 }67 } 3、在hibernate.cfg.xml⽂件中引⼊上⾯两个类的映射1 <mapping class="erBean2" />2 <mapping class="com.st.bean5.RoleBean2" /> 4、在BeanTest中添加相应的测试⽅法:1 @Test2 public void bean4test1(){3 Session session = HibernateTools.openSession();4 Transaction tran = session.beginTransaction();5 //⾸先在dept中新增⼀条数据,再关联的在employee中新增⼀条数据6 //DeptBean2 dept = new DeptBean2();7 //先读去dept中的数据,再在读取的基础上关联的在employee中新增⼀条数据8 DeptBean2 dept = (DeptBean2) session.get(DeptBean2.class,1L); //1L代表主键9 EmployeeBean2 emp = new EmployeeBean2();10 //dept.setName("技术部");11 emp.setName("陈泽俊");12 emp.setSex("男");13 emp.setJob("STM32");14 dept.getEmp().add(emp);15 session.save(dept);16 //确认提交事物17 mit();⼆、多对多关系 1、新建⼀个com.st.bean4 包,往包⾥⾯添加两个含有注解的类 a)、UserBean2:1 package com.st.bean5;2 import java.util.HashSet;3 import java.util.Set;45 import javax.persistence.Column;6 import javax.persistence.Entity;7 import javax.persistence.GeneratedValue;8 import javax.persistence.Id;9 import javax.persistence.JoinColumn;10 import javax.persistence.JoinTable;11 import javax.persistence.ManyToMany;12 import javax.persistence.Table;1314 import org.hibernate.annotations.Cascade;15 import org.hibernate.annotations.CascadeType;16 import org.hibernate.annotations.GenericGenerator;1718 @Entity //实体19 @Table(name="T_USER") //表名20 @GenericGenerator(name="genID", strategy="increment") //声明主键⽣成策略21 public class UserBean2 {22 @Id //指定主键23 @GeneratedValue(generator="genID") //设定主键⽣成策略24 @Column(name="ID") //指定类的属性和表的字段的对应关系25 private long id;26 @Column(name="NAME")27 private String name;28 @Column(name="SEX")29 private String sex;30 @ManyToMany //指定多对多关系31 @Cascade(value={CascadeType.SAVE_UPDATE}) //设置级联关系32 @JoinTable(name="USER_ROLE", //指定第三张表33 joinColumns={@JoinColumn(name="USER_ID")}, //本表与中间表的外键对应34 inverseJoinColumns={@JoinColumn(name="ROLE_ID")}) //另⼀张表与第三张表的外键的对应关系35 private Set<RoleBean2> role = new HashSet<RoleBean2>();36 public long getId() {37 return id;38 }39 public void setId(long id) {40 this.id = id;41 }42 public String getName() {43 return name;44 }45 public void setName(String name) {46 = name;47 }48 public String getSex() {49 return sex;50 }51 public void setSex(String sex) {52 this.sex = sex;53 }54 public Set<RoleBean2> getRole() {55 return role;56 }57 public void setRole(Set<RoleBean2> role) {58 this.role = role;59 }60 @Override61 public String toString() {62 return "UserBean [id=" + id + ", name=" + name + ", sex=" + sex63 + ", role=" + role + "]";64 }65 } b)、RoleBean类:1 package com.st.bean5;2 import java.util.HashSet;34 import java.util.Set;56 import javax.persistence.Column;7 import javax.persistence.Entity;8 import javax.persistence.GeneratedValue;9 import javax.persistence.Id;10 import javax.persistence.JoinColumn;11 import javax.persistence.JoinTable;12 import javax.persistence.ManyToMany;13 import javax.persistence.Table;1415 import org.hibernate.annotations.Cascade;16 import org.hibernate.annotations.CascadeType;17 import org.hibernate.annotations.GenericGenerator;1819 @Entity //实体20 @Table(name="T_ROLE") //表名21 @GenericGenerator(name="genID", strategy="increment")//声明主键⽣成策略22 public class RoleBean2 {23 @Id //主键24 @GeneratedValue(generator="genID") //设置主键⽣成策略25 @Column(name="ID") //类中的属性与表的字段的对应关系26 private long id;27 @Column(name="POST")28 private String post;//职位29 @Column(name="PAY")30 private int pay; //薪资31 @ManyToMany //多对多关系32 @Cascade(value={CascadeType.SAVE_UPDATE}) //级联关系33 @JoinTable(name="USER_ROLE", //中间表的名称34 joinColumns={@JoinColumn(name="ROLE_ID")}, //本表与中间表的外键对应关系35 inverseJoinColumns={@JoinColumn(name="USER_ID")}) //另⼀张表与中间表的外键的对应关系36 private Set<UserBean2> user = new HashSet<UserBean2>();3738 public long getId() {39 return id;40 }41 public void setId(long id) {42 this.id = id;43 }44 public String getPost() {45 return post;46 }47 public void setPost(String post) {48 this.post = post;49 }50 public int getPay() {51 return pay;52 }53 public void setPay(int pay) {54 this.pay = pay;55 }56 public Set<UserBean2> getUser() {57 return user;58 }59 public void setUser(Set<UserBean2> user) {60 er = user;61 }62 @Override63 public String toString() {64 return "RoleBean [id=" + id + ", post=" + post + ", pay=" + pay + "]";65 }66 } 2、在hibernate.cfg.xml中引⼊UserBean2和RoleBean2这两个类的映射:1 <mapping class="erBean2" />2 <mapping class="com.st.bean5.RoleBean2" /> 3、在BeanTest类中添加测试⽅法:1 @Test2 public void bean5test1(){3 // 获取⼀个会话4 Session session = HibernateTools.openSession();5 //开启⼀次事物6 Transaction tran = session.beginTransaction();7 UserBean2 user = new UserBean2();8 // RoleBean2 role = (RoleBean2) session.get(RoleBean2.class,1L);9 RoleBean2 role = new RoleBean2();1011 user.setName("汪⽂仕");12 user.setSex("男");1314 role.setPost("博⼠");15 role.setPay(10000);1617 role.getUser().add(user);18 session.save(role);19 //确认提交事物20 mit();21 }22 @Test23 public void bean5test2(){24 // 获取⼀个会话25 Session session = HibernateTools.openSession();26 /* List<UserBean> list = session.createCriteria(UserBean.class).list();27 for(UserBean user : list)28 System.out.println(user);*/29 String hql = "select new Map( as name,u.sex as sex,r.post as post,r.pay as pay) from UserBean2 u join u.role r";30 List<Map<String,Object>> list = session.createQuery(hql).list();31 for(Map<String,Object> data : list)32 System.out.println(data);33 }三、注意: 1、引⼊了注解需要的jar包后要先删除Java EE 5 Library这个库,否则会两个jar包中的类产⽣冲突 2、在多表操作时最好设置级联关系,不然对表操作时要先读取⼀个类的数据,再将新建的⼀个类的数据添加到这个类上才成功对三张表同时操作。
Hibernate(V)——一对多与多对多关联关系映射(xml与注解)总结

Hibernate(V)——一对多与多对多关联关系映射(xml与注解)总结引言简要介绍Hibernate框架以及关联关系映射在数据库设计中的重要性。
Hibernate关联关系映射概述关联关系的重要性讨论在现实世界中对象间关系的重要性以及如何在数据库中表示这些关系。
Hibernate关联关系类型列举Hibernate支持的关联关系类型,包括一对一、一对多、多对一和多对多。
一对多关联关系映射概念解释解释一对多关联关系的概念,例如一个部门拥有多个员工。
XML映射方式详细描述如何在XML映射文件中配置一对多关联关系。
实体类定义展示一对多关系中实体类的Java代码示例。
XML映射文件提供一对多关系映射的XML配置示例。
注解映射方式详细描述如何使用注解配置一对多关联关系。
实体类定义展示使用注解的一对多关系中实体类的Java代码示例。
注解配置提供一对多关系映射的注解配置示例。
多对多关联关系映射概念解释解释多对多关联关系的概念,例如学生和课程之间的关联。
XML映射方式详细描述如何在XML映射文件中配置多对多关联关系。
实体类定义展示多对多关系中实体类的Java代码示例。
XML映射文件提供多对多关系映射的XML配置示例。
注解映射方式详细描述如何使用注解配置多对多关联关系。
实体类定义展示使用注解的多对多关系中实体类的Java代码示例。
注解配置提供多对多关系映射的注解配置示例。
关联关系映射的高级特性级联操作讨论级联保存、更新和删除的概念及其配置。
双向关系管理解释如何管理双向关联关系,确保数据的一致性。
延迟加载与即时加载讨论延迟加载和即时加载的概念及其在关联关系中的应用。
实践案例分析一对多关联关系案例通过一个具体的一对多关联关系案例,展示映射配置和数据操作。
多对多关联关系案例通过一个具体的多对多关联关系案例,展示映射配置和数据操作。
常见问题与解决方案一对多关联关系常见问题列举一对多关联关系映射中可能遇到的问题及其解决方案。
hibernate关系映射注解配置

1. Hibernate Annotation关系映射有下面几种类型:1)一对一外键关联映射(单向)2)一对一外键关联映射(双向)3)一对一主键关联映射(不重要,有需要看下文档即可)在实际中很少用,使用注解@PrimaryKeyJoinColumn意思是说,我的主键去参考另外一张表中的主键,作为我的主键,但是在我测试使用注解一对一主键关联映射,在生成表的时候,数据库中并没有生成关联,使用XML映射可以生成。
Annotation注解一对一主键关联映,有些bug。
不过没空去研究它。
因为在实际开发中一对一很少用。
在实际开发中我机会没有用过,主键关联就更少了4)多对一关联映射(单向)5)一对多关联映射(单向)6)一对多关联映射(双向)7)多对多关联映射(单向)8)多对多关联映射(双向)2.介绍各种映射用法1)一对一外键关联映射(单向)Husband ---> Wifepublic class Husband{private Wife wife;@OneToOne(cascade=CascadeType.ALL)@JoinColumn(name="wife_id",unique=true)public Wife getWife(){…}…}public class Wife{}一对一外键关联,使用@OneToOne,并设置了级联操作@JoinColum设置了外键的名称为wife_id(数据库字段名),如果不设置,则默认为另一类的属性名+ _id外键的值是唯一的(unique),不可重复,与另一类的主键一致2)一对一外键关联映射(双向)Husband <---> Wifepublic class Husband{private Wife wife;@OneToOne(cascade=CascadeType.ALL)@JoinColumn(name="wife_id",unique=true)public Wife getWife(){…}...}public class Wife{private Husband husband;@OneToOne(mappedBy="wife",cascade=CascadeType.ALL)public Husband getHusband(){…}...}一对一双向关联关系,使用@OneToOne注意:需要加上mappedBy="wife",如果不加上的话,Wife也会生成一个外键(husband_id)。
Hibernate中用注解配置一对多双向关联和多对一单向关联

Hibernate中⽤注解配置⼀对多双向关联和多对⼀单向关联Hibernate中⽤注解配置⼀对多双向关联和多对⼀单向关联Hibernate提供了Hibernate Annotations扩展包,使⽤注解完成映射。
在Hibernate3.3之前,需单独下载注解开发包配置持久化类配置关联关系下⾯我们先从多对⼀单向关联关系讲起,多对⼀单向关联就是在多的⼀⽅植⼊⼀的⼀⽅的主键作为外键,下⾯我们先进⾏初始配置,在配置的过程中我们会遇到⼀个问题就是⽆论⽤load还是get都不会出现延迟加载,那么我们应该如何设置为要延迟加载,这样做的好处是可以在⽤的时候才加载对应的信息,节约内存中,延迟加载⼤致可以分为两类,⼀类是延迟属性加载,另⼀类是延迟关联实体加载。
普通属性:分两种情况,⼀种是集合属性,⼀种是⾮集合属性(如String、Integer......)集合属性的延迟加载通过PersistentSet、 PersistentList、PersistentBag、PersistentMap、PersistentSortedMap、 PersistentSortedSet作为代理类来实现,代理类中保存了session以及owner属性,owner属性表⽰了集合属性所属的one 侧的实体。
⾮集合类属性的延迟加载相对⽐较复杂。
仅通过@Basic(fetch = ZY)注解是⽆法实现延迟加载的。
需要让实体实现FieldHandled接⼝,声明FieldHandler属性,通过拦截器原理注⼊对应的FieldHandler属性,起到类似于上述代理类的作⽤,FieldHandler 同样也保持了session,以及需要延迟加载的属性。
我们发现对⾮集合属性即时设置了@Basic(fetch = ZY)仍⽆法实现延迟加载,可以看⽣成的sql语句接下来我们会对⼀对多单向关联进⾏测试,验证对集合类属性,是否可以起到延迟加载的功能注意:不可以对有关联关系的属性设置@Transient配置多对⼀的单向关联关系⽰例1 package cn.happy.entity;23 import javax.persistence.Basic;4 import javax.persistence.Column;5 import javax.persistence.Entity;6 import javax.persistence.FetchType;7 import javax.persistence.GeneratedValue;8 import javax.persistence.GenerationType;9 import javax.persistence.Id;10 import javax.persistence.JoinColumn;11 import javax.persistence.ManyToOne;12 import javax.persistence.SequenceGenerator;13 import javax.persistence.Table;14 import javax.persistence.Transient;1516 @Entity17 @Table(name = "EMP")18public class Emp {19 @Id20 @Column(name = "EMPNO")21 @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "emp_num")22 @SequenceGenerator(name = "emp_num", sequenceName = "emp_num_id", allocationSize = 1, initialValue = 1)23private Integer empNo;2425 @Column(name = "EMPNAME")26private String empName;2728 @ManyToOne()29 @JoinColumn(name = "DEPTNO")30/*@Basic(fetch=ZY)*/31private Dept dept;323334public Emp() {35 super();36 }3738public Emp(Integer empNo, String empName) {39 super();40this.empNo = empNo;41this.empName = empName;42 }4344public Integer getEmpNo() {45return empNo;46 }4748public void setEmpNo(Integer empNo) {49this.empNo = empNo;50 }5152public String getEmpName() {5556public void setEmpName(String empName) {57this.empName = empName;58 }5960public Dept getDept() {61return dept;62 }6364public void setDept(Dept dept) {65this.dept = dept;66 }67 }1package cn.happy.entity;23import java.util.HashSet;4import java.util.Set;56import javax.persistence.CascadeType;7import javax.persistence.Column;8import javax.persistence.Entity;9import javax.persistence.GeneratedValue;10import javax.persistence.GenerationType;11import javax.persistence.Id;12import javax.persistence.JoinColumn;13import javax.persistence.OneToMany;14import javax.persistence.SequenceGenerator;15import javax.persistence.Table;16import javax.persistence.Transient;1718import org.hibernate.annotations.Cascade;1920 @Entity21 @Table(name = "DEPT")22public class Dept {23 @Id24 @Column(name = "DEPTNO")25 @GeneratedValue(strategy=GenerationType.SEQUENCE,generator="dept_num")26 @SequenceGenerator(name="dept_num",sequenceName="dept_num_no",allocationSize=1,initialValue=1) 27private Integer deptNo;2829 @Column(name = "DEPTNAME")30private String deptName;313233public Integer getDeptNo() {34return deptNo;35 }3637public void setDeptNo(Integer deptNo) {38this.deptNo = deptNo;39 }4041public String getDeptName() {42return deptName;43 }4445public void setDeptName(String deptName) {46this.deptName = deptName;47 }48 }1/**2 * 注解测试多对⼀映射员⼯表(多)对应部门表(⼀)的映射,即只在员⼯表中植⼊部门表的信息3 * */4 @Test5public void manytooneSingle(){67/**8 * 查询操作9 * **/10/*SessionFactory sf=new AnnotationConfiguration().configure().buildSessionFactory();11 Session session = sf.openSession();1213 Emp emp=(Emp)session.load(Emp.class, 4);1415 System.out.println(emp.getEmpName()+"\t"+emp.getDept().getDeptName());*/1617/**20 SessionFactory sf=new AnnotationConfiguration().configure().buildSessionFactory();21 Session session = sf.openSession();22 Transaction tx = session.beginTransaction();23 Dept dept = (Dept)session.load(Dept.class, 3);2425 Emp emp=new Emp();26 emp.setEmpName("户梦艳");27 emp.setEmpNo(001);28 emp.setDept(dept);2930 Emp emp2=new Emp();31 emp2.setEmpName("户梦艳2");32 emp2.setEmpNo(002);33 emp2.setDept(dept);3435 session.save(emp);36 session.save(emp2);37 mit();38 session.close();394041 }⼀对多双单向配置1 package cn.happy.entity;23 import java.util.HashSet;4 import java.util.Set;56 import javax.persistence.CascadeType;7 import javax.persistence.Column;8 import javax.persistence.Entity;9 import javax.persistence.GeneratedValue;10 import javax.persistence.GenerationType;11 import javax.persistence.Id;12 import javax.persistence.JoinColumn;13 import javax.persistence.OneToMany;14 import javax.persistence.SequenceGenerator;15 import javax.persistence.Table;16 import javax.persistence.Transient;171819 @Entity20 @Table(name="Dept")21public class Dept {22 @Id23 @GeneratedValue(strategy=GenerationType.SEQUENCE,generator="dept_num")24 @SequenceGenerator(name="dept_num",sequenceName="dept_num_no",allocationSize=1,initialValue=1) 25private Integer deptNo;26 @Column27private String deptName;282930 @OneToMany(cascade={CascadeType.ALL})31 @JoinColumn(name="deptno")32private Set<Emp> emps=new HashSet<Emp>();3334public Set<Emp> getEmps() {35return emps;36 }3738public void setEmps(Set<Emp> emps) {39this.emps = emps;40 }4142public Integer getDeptNo() {43return deptNo;44 }4546public void setDeptNo(Integer deptNo) {47this.deptNo = deptNo;48 }4950public String getDeptName() {51return deptName;52 }5354public void setDeptName(String deptName) {55this.deptName = deptName;57 }1 package cn.happy.entity;23 import javax.persistence.Basic;4 import javax.persistence.Column;5 import javax.persistence.Entity;6 import javax.persistence.FetchType;7 import javax.persistence.GeneratedValue;8 import javax.persistence.GenerationType;9 import javax.persistence.Id;10 import javax.persistence.JoinColumn;11 import javax.persistence.ManyToOne;12 import javax.persistence.SequenceGenerator;13 import javax.persistence.Table;14 import javax.persistence.Transient;1516 import org.hibernate.bytecode.javassist.FieldHandled;17 import org.hibernate.bytecode.javassist.FieldHandler;181920 @Entity21 @Table(name = "EMP")22public class Emp {23242526 @Id27 @GeneratedValue(strategy=GenerationType.SEQUENCE,generator="emp_num")28 @SequenceGenerator(name="emp_num",sequenceName="emp_num_no",allocationSize=1,initialValue=9) 29private Integer empNo;3031 @Column32private String empName;333435// @ManyToOne36// @JoinColumn(name="deptno")37// @Basic(fetch=ZY)38// private Dept dept;39//40// public Dept getDept() {41// return dept;42// }43//44// public void setDept(Dept dept) {45// this.dept = dept;46// }4748public Emp() {49 super();50 }5152public Emp(Integer empNo, String empName) {53 super();54this.empNo = empNo;55this.empName = empName;56 }5758public Integer getEmpNo() {59return empNo;60 }6162public void setEmpNo(Integer empNo) {63this.empNo = empNo;64 }6566public String getEmpName() {67return empName;68 }6970public void setEmpName(String empName) {71this.empName = empName;72 }737475 }2 * 测试⼀对多单向添加操作3 * */4 @Test5public void insertOneToManySingle(){6 Emp emp=new Emp();7 emp.setEmpName("李⼩鹏");89 Emp emp2=new Emp();10 emp2.setEmpName("王想想");1112 Dept dept=new Dept();13 dept.setDeptName("教务部");14//设置级联操作15 dept.getEmps().add(emp);16 dept.getEmps().add(emp2);1718 session.save(dept);19 mit();20 System.out.println("insert ok");2122 }1/**2 * 测试⼀对多单向查询操作3 * */4 @Test5public void selectOneToManySingle(){6 Dept dept = (Dept)session.load(Dept.class, 1);7 System.out.println("======================");8 System.out.println("部门名称:"+dept.getDeptName());9 System.out.println("=======================");10//体现了延迟加载11for (Emp emp : dept.getEmps()) {12 System.out.println("雇员名称:"+emp.getEmpName());13 }14//Emp emp = (Emp)session.load(Emp.class, 1);151617 }⼀对多双向配置1 package cn.happy.entity;23 import java.util.HashSet;4 import java.util.Set;56 import javax.persistence.CascadeType;7 import javax.persistence.Column;8 import javax.persistence.Entity;9 import javax.persistence.GeneratedValue;10 import javax.persistence.GenerationType;11 import javax.persistence.Id;12 import javax.persistence.JoinColumn;13 import javax.persistence.OneToMany;14 import javax.persistence.SequenceGenerator;15 import javax.persistence.Table;16 import javax.persistence.Transient;171819 @Entity20 @Table(name="Dept")21public class Dept {22 @Id23 @GeneratedValue(strategy=GenerationType.SEQUENCE,generator="dept_num")24 @SequenceGenerator(name="dept_num",sequenceName="dept_num_no",allocationSize=1,initialValue=1) 25private Integer deptNo;26 @Column27private String deptName;282930 @OneToMany(mappedBy="dept",cascade={CascadeType.ALL})3132private Set<Emp> emps=new HashSet<Emp>();3340 }4142public Integer getDeptNo() {43return deptNo;44 }4546public void setDeptNo(Integer deptNo) {47this.deptNo = deptNo;48 }4950public String getDeptName() {51return deptName;52 }5354public void setDeptName(String deptName) {55this.deptName = deptName;56 }57 }1 package cn.happy.entity;23 import javax.persistence.Basic;4 import javax.persistence.Column;5 import javax.persistence.Entity;6 import javax.persistence.FetchType;7 import javax.persistence.GeneratedValue;8 import javax.persistence.GenerationType;9 import javax.persistence.Id;10 import javax.persistence.JoinColumn;11 import javax.persistence.ManyToOne;12 import javax.persistence.SequenceGenerator;13 import javax.persistence.Table;14 import javax.persistence.Transient;1516 import org.hibernate.bytecode.javassist.FieldHandled;17 import org.hibernate.bytecode.javassist.FieldHandler;181920 @Entity21 @Table(name = "EMP")22public class Emp {23242526 @Id27 @GeneratedValue(strategy=GenerationType.SEQUENCE,generator="emp_num")28 @SequenceGenerator(name="emp_num",sequenceName="emp_num_no",allocationSize=1,initialValue=9) 29private Integer empNo;3031 @Column32private String empName;333435 @ManyToOne36 @JoinColumn(name="deptno")37 @Basic(fetch=ZY)38private Dept dept;3940public Dept getDept() {41return dept;42 }4344public void setDept(Dept dept) {45this.dept = dept;46 }4748public Emp() {49 super();50 }5152public Emp(Integer empNo, String empName) {53 super();54this.empNo = empNo;55this.empName = empName;56 }5764 }6566public String getEmpName() {67return empName;68 }6970public void setEmpName(String empName) {71this.empName = empName;72 }737475 }1/**2 * 双向⼀对多的添加操作3 * */4 @Test5public void oneToManyDouble(){6 Dept dept=new Dept();7 dept.setDeptName("财务部");89 Emp emp=new Emp();10 emp.setEmpName("邹乐");11 emp.setDept(dept);1213 Emp emp2=new Emp();14 emp2.setEmpName("范⼦阳");15 emp2.setDept(dept);161718 dept.getEmps().add(emp);19 dept.getEmps().add(emp2);2021 session.save(dept);22 mit();23 }241/**2 * 双向⼀对多的查询操作3 * */4 @Test5public void selectOneToManyDouble(){67 Dept dept = (Dept)session.load(Dept.class, 1);8 System.out.println("部门名称:"+dept.getDeptName());9for (Emp emp : dept.getEmps()) {10 System.out.println("职⼯姓名:"+emp.getEmpName());11 }1213 System.out.println("==================================================");1415 Emp emp = (Emp)session.load(Emp.class, 1);16 System.out.println("职⼯姓名:"+emp.getEmpName()+"\t部门名称:"+emp.getDept().getDeptName());17 }18。
hibernate注解处理映射关系

3 / 14
private int age; private ClassRoom room;
@ManyToOne(fetch=ZY) ---> ManyToOne 指定了多对一的关系,fetch=ZY 属性 表示在多的那一方通过延迟加载的方式加载对象(默认不是延迟加载)
return name; }
--->
指定了 OneToOne 的关联关系,mappedBy 同样指定由对方来进
5 / 14
public void setName(String name) {
= name; }
}
IDCard 类:
@Entity @Table(name="t_id_card") public class IDCard {
this.room = room; } @Id @GeneratedValue public int getId() {
return id; } public void setId(int id) {
this.id = id; } public String getName() {
return name; } public void setName(String name) {
@Entity @Table(name="t_person") public class Person {
private int id; private String name; private IDCard card;
@OneToOne(mappedBy="person") 行维护关联关系
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Hibernate(6)——一对多和多对多关联关系映射(xml和注解)总结
涉及的知识点总结如下:
∙One to Many 映射关系
o多对一单向外键关联(XML/Annotation)
o一对多单向外键关联(XML/Annotation)
o懒加载和积极加载
o一对多双向外键关联(XML/Annotation)
∙Many to Many 映射关系
o多对多单向外键关联(XML/Annotation)
o多对多双向外键关联(XML/Annotation)
o set的inverse元素详解
∙问题小结
∙关联关系的优缺点
多对一单向外键关联关系
注意多对一关联是多方持有一方的引用。
看一个例子,去淘宝购物,那么一个淘宝用户可以对应多个购物订单,如图所示:
多的一方是Orders,持有一方的引用,也就是Users,而在Users中无需作任何定义,从订单到用户的关系是单向多对一关联。
对应数据库就是:
还有比如说学生和班级的关系,多个学生可以属于同一个班级,这就是从学生到班级也是典型的单向多对一关系,看代码实现:
基于注解的多对一单向外键关联:
单向多对一关联中,多方需要持有一方的引用,那么多方(学生类)需要额外配置,需要对持有的一方引用使用注解@ManyToOne (cascade={CascadeType.ALL}, fetch=FetchType.EAGER),设置为级联操作和饥渴的抓取策略,@JoinColumn(name="cid"),而一方(教室类)无需做任何多方的定义。
注意;多方必须保留一个不带参数的构造器!
import ;
import ;
import ;
//班级类,在多对一关系中属于一的方,不持有其他多余的配置,反而是被多方持有
public class ClassRoom {
private int cid;//班级编号
private String cname;//班级名称
// 自动增长的主键
@Id
@GeneratedValue
public int getCid() {
return cid;
}
public void setCid(int cid) {
this.cid = cid;
}
public String getCname() {
return cname;
}
public void setCname(String cname) {
ame = cname;
}
}
View Code
一方——班级类无需做多余的定义,下面是多方——学生实体和配置:
import ;
import ;
import ;
import ;
import ;
import ;
import ;
//学生实体类,属于多对一的多方,持有班级(一方)的引用@Entity
public class Students {
private int sid; //编号
private String sname; //姓名
private ClassRoom classroom;//学生班级
//注意:多方一定要显式的定义不带参数的构造方法
public Students() {
public Students(String sname)
{
this.sname = sname;
}
// 多方使用注解:@ManyToOne
// fetch=FetchType.EAGER,急加载,加载一个实体时,定义急加载的属性会立即从数据库中加载。
// 全部级联操作,referencedColumnName显式设置数据库字段名cid,不写默认就是和name一样的。
@ManyToOne (cascade={CascadeType.ALL}, fetch=FetchType.EAGER)
@JoinColumn(name="cid",referencedColumnName="cid")
public ClassRoom getClassroom() {
return classroom;
}
public void setClassroom(ClassRoom classroom) {
this.classroom = classroom;
}
// 自动增长主键
@Id
@GeneratedValue
public int getSid() {
return sid;
}
public void setSid(int sid) {
this.sid = sid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
}
View Code
下面测试:先生成数据库脚本,再进行学生对象的插入
public class TestStudentsByAnno {。