Hibernate框架基础——cascade属性
我们以部门和员工的关系为例讲解一对多关联关系映射时,删除部门时,如果部门有关联的员工且inverse属性为false,那么由于可以维护关联关系,它就会先把关联的员工的外键列设为null值,再删除自己。但是此刻希望删除部门时,就附带着把该部门下的所有员工都删掉,这时就需要引入cascade属性了。
级联(cascade)
当Hibernate持久化一个临时对象时,在默认情况下,它不会自动持久化所关联的其他临时对象,而是会抛出TransientObjectException。如果设定many-to-one元素的cascade属性为save-update的话,可实现自动持久化所关联的对象。如:
<many-to-one name="customer" column="CUSTOMER_ID" class="..Customer"cascade="save-update"not-null="true" />
级联指的是当主控方执行操作时,关联对象(被动方)是否同步执行同一操作。
级联风格
每个Hibernate session的基本操作包括persist()、merge()、saveOrUpdate()、delete()、lock()、refresh()、evict()、replicate(),这些操作都有对应的级联风格(cascade style)。这些级联风格(cascade style)风格分别命名为persist、merge、save-update、delete、lock、refresh、evict、replicate。
级联风格 | Session中的方法 |
---|---|
persist | persist() |
merge | merge() |
save-update | save()、update()、saveOrUpdate() |
delete | delete() |
lock | lock() |
refresh | refresh() |
evict | evict() |
replicate | replicate() |
如果你希望一个操作被顺着关联关系级联传播,你必须在映射文件中指出这一点。
指定级联风格:
<one-to-one name="person" cascade="persist" />
级联风格(cascade style)是可组合的:
<one-to-one name="person" cascade="persist,delete" />
你可以使用cascade=”all”来指定全部操作都顺着关联关系级联(cascaded)。默认值是cascade=”none”,即任何操作都不会被级联(cascaded)。
在对象/关系映射文件中,用于映射持久化类之间关联关系的元素,如<set>
、<many-to-one>
和<one-to-one>
都有一个cascade属性。
案例分析——cascade属性
还是回到开头我们提出的需求,即删除部门时,就附带着把该部门下的所有员工都删掉。要满足这个需求,我们最好新建一个普通java工程,如Hibernate_Test,然后在cn.itcast.f_hbm_oneToManyb包下新建持久化类——Department.java和Employee.java。
持久化类——Department.java的代码如下:
/*** 部门* @author li ayun**/
public class Department {private Integer id;private String name;private Set<Employee> employees = new HashSet<Employee>(); // 关联的很多个员工public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Set<Employee> getEmployees() {return employees;}public void setEmployees(Set<Employee> employees) {this.employees = employees;}@Overridepublic String toString() {return "[Department: id=" + id + ", name=" + name + "]";}
}
持久化类——Employee.java的代码如下:
/*** 员工* @author li ayun**/
public class Employee {private Integer id;private String name;private Department department; // 关联的部门对象public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Department getDepartment() {return department;}public void setDepartment(Department department) {this.department = department;}@Overridepublic String toString() {return "[Employee: id=" + id + ", name=" + name + "]";}
}
由于我们先前就分析过各个持久化类在数据库中所对应的表的结构,所以我们很容易就写出各个持久化类相应的映射配置文件了。
先在cn.itcast.f_hbm_oneToMany包中创建Department类对应的映射配置文件——Department.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="cn.itcast.f_hbm_oneToMany"><class name="Department" table="department"><id name="id"><generator class="native"></generator> </id><property name="name" /><!-- employees属性,Set集合,表达的是本类与Employee的一对多的关系class属性:关联的实体类型key子元素:对方表中的外键列(多方的哪个表)inverse属性:默认为false,表示本方维护关联关系。如果为true,表示本方不维护关联关系。只是影响是否能设置外键列的值(设成有效值或是null值),对获取信息没有任何影响。cascade属性:默认为none,代表不级联。级联是指操作主对象时,对关联的对象也做相同的操作。可设为:delete,save-update,all,none,...--><set name="employees" cascade="save-update,delete"><key column="departmentId"></key><one-to-many class="Employee"/></set></class>
</hibernate-mapping>
在<set>
元素中设置cascade=”save-update,delete”,即表示只须保存/修改某部门,该部门下的所有员工都将保存/修改,或者删除部门时,就附带着把该部门下的所有员工都删掉。
然后也是在该包中创建Employee类对应的映射配置文件——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="cn.itcast.f_hbm_oneToMany"><class name="Employee" table="employee"><id name="id"><generator class="native"></generator> </id><property name="name" type="string" column="name" /><!-- department属性,表达的是本类与Department的多对一的关系class属性:关联的实体类型column属性:外键列(引用关联对象的表的主键)--><many-to-one name="department" class="Department" column="departmentId"></many-to-one></class>
</hibernate-mapping>
接下来,我们从以下2个方面来编写代码进行测试:
- 保存新数据,并有关联关系。
- 删除对象,看对关联对象的影响。
所以,我们要在cn.itcast.f_hbm_oneToMany包中编写一个单元测试类——Application.java。
public class Application {private static SessionFactory sessionFactory = new Configuration() //.configure() //.addClass(Department.class) // 添加Hibernate实体类(加载对应的映射文件).addClass(Employee.class) // 添加Hibernate实体类(加载对应的映射文件).buildSessionFactory();// 保存,有关联关系@Testpublic void testSave() {Session session = sessionFactory.openSession();session.beginTransaction();// -------------------------------------------// 新建对象Department department = new Department();department.setName("开发部");Employee employee1 = new Employee();employee1.setName("张三");Employee employee2 = new Employee();employee2.setName("李四");// 关联起来employee1.setDepartment(department); // 告诉员工他属于哪个部门employee2.setDepartment(department);department.getEmployees().add(employee1); // 告诉部门它有两个关联的员工department.getEmployees().add(employee2);// 保存session.save(department); // 保存部门// -------------------------------------------session.getTransaction().commit();session.close();}// 删除对象,对关联对象的影响@Testpublic void testDelete() {Session session = sessionFactory.openSession();session.beginTransaction();// -------------------------------------------// 删除部门方(一方)Department department = (Department) session.get(Department.class, 1);session.delete(department);// -------------------------------------------session.getTransaction().commit();session.close();}
}
这样,当保存部门时,会级联保存该部门下的所有员工,或者删除部门时,就会级联删除该部门下的所有员工。我们也可以配置员工级联删除部门,但这样做,在业务上是极不合理的。
总结
一般是多对一和多对多的时候不使用级联,一对一和一对多可以使用级联,这两种情况使用级联比较多,总结来说,这个对象归你控制,你就能够级联,它不归你一个人所有,那你就不要级联。
还有一点要注意,inverse属性和cascade属性毛关系都没有。
Hibernate框架基础——cascade属性相关推荐
- (转)Hibernate框架基础——cascade属性
http://blog.csdn.net/yerenyuan_pku/article/details/52760010 我们以部门和员工的关系为例讲解一对多关联关系映射时,删除部门时,如果部门有关联的 ...
- (转)Hibernate框架基础——一对多关联关系映射
http://blog.csdn.net/yerenyuan_pku/article/details/52746413 上一篇文章Hibernate框架基础--映射集合属性详细讲解的是值类型的集合(即 ...
- (转)Hibernate框架基础——映射普通属性
http://blog.csdn.net/yerenyuan_pku/article/details/52739871 持久化对象与OID 对持久化对象的要求 提供一个无参的构造器.使Hibernat ...
- (转)Hibernate框架基础——Java对象持久化概述
http://blog.csdn.net/yerenyuan_pku/article/details/52732990 Java对象持久化概述 应用程序的分层体系结构 基于B/S的典型三层架构 说 ...
- Hibernate框架基础——Hibernate入门
Hibernate入门 Hibernate介绍 Hibernate是一个基于jdbc的开源的持久化框架,是一个优秀的ORM实现,它很大程度的简化了dao层编码工作.Hibernate对JDBC访问数据 ...
- (转)Hibernate框架基础——映射主键属性
http://blog.csdn.net/yerenyuan_pku/article/details/52740744 本文我们学习映射文件中的主键属性,废话不多说,直接开干. 我们首先在cn.it ...
- (转)Hibernate框架基础——映射集合属性
http://blog.csdn.net/yerenyuan_pku/article/details/52745486 集合映射 集合属性大致有两种: 单纯的集合属性,如像List.Set或数组等集合 ...
- (转) Hibernate框架基础——操纵持久化对象的方法(Session中)
http://blog.csdn.net/yerenyuan_pku/article/details/52761021 上一篇文章中我们学习了Hibernate中java对象的状态以及对象的状态之间如 ...
- (转)Hibernate框架基础——在Hibernate中java对象的状态
http://blog.csdn.net/yerenyuan_pku/article/details/52760627 在Hibernate中java对象的状态 Hibernate把对象分为4种状态: ...
最新文章
- 课堂练习---统计空格流程图、Jackson图
- android raw 引用,Android 资源-raw和assets
- java trim()函数_Java - split()函数和trim()函数的使用方法
- 计算机网络的分层结构、协议、服务和接口
- ubuntu 安装nvidia 驱动后无法进入桌面(循环进入登录界面 )
- 商用密码产品认证-数字证书认证系统
- 科赫雪花java_java递归实现科赫雪花
- 程序读取凡人修仙传热度数据
- UNI-APP实现扫描二维码
- FPGA + labwindows/CVI 2017 串口通信 电子钟
- 【UEFI基础】PCD
- 脑机接口取得重大突破
- DNS服务器原理介绍(一)
- 关于cos(x^2)的傅里叶逆变换(Inverse Fourier Transform)
- 表白生日祝福和3D表白相册
- c语言多组变量输入数据,C/C++中输入多组数据的方法
- 用c语言录入3组学生数据编程,学生信息管理系统C语言编程
- 《RCLane:Relay Chain Prediction for Lane Detection》论文笔记
- 安装完华为的opengauss 后,能ping通服务地址,telnet不通端口
- 3ds模型--完善TGA纹理显示