1. 级联关系

在Hibernate程序中持久化的对象之间会通过关联关系互相引用。对象进行保存、更新和删除等操作时,有时需要被关联的对象也执行相应的操作,如:假设需要关联关系的主动方对象执行操作时,被关联的对象也会同步执行同一操作。这一问题可以通过使用Hibernate的级联(cascade)功能来解决。

例如:当试图删除顾客对象时,通过级联关系让Hibernate决定是否删除该对象对应的所有订单对象。
cascade是<set>元素的一个属性,该属性常用值及描述如下表:
 属性值    描述 
 none                    默认值,表示关联对象之间无级联操作 
 save-update 表示主动方对象在调用save(),update()和saveOrUpdate()方法时对被关联对象执行保存或更新操作 
 delete  表示主动方对象在调用delete()方法时被关联对象执行删除操作
 delete-orphan 用在1-N关联中,表示主动方对象调用delete()方法时删除不被任何一个关联对象所引用的关联对象,多用于父子关联对象中。 
 all  等价于save-update和delete的联合使用

注意:在实际开发中,级联通常用在1-N和1-1 关联关系中。而对于N-1和N-N关联使用级联操作则没有意义。此外,cascade属性值save-update最为常用。

 
  
接下来将演示如何使用级联,以及级联使用哪些SQL语句?
假设Customer类、Order类如下:

要求:当添加一个顾客对象时,同时保存该顾客的所有订单。在BusinessService中添加如下代码:

 public class BusinessService{
public static void main(String[] args){
Customer customer = new Customer("lisi","123","李四","青岛","123123");
Order order = new Order("3",new Date(),1000.0);//并没有传入customer对象
//建立关联关系,实现级联保存
customer.getOrders().add(order); Session session = HibernateUtils.getSession(); Transaction trans = session.beginTransaction();
session.save(customer);
trans.commit();
HibernateUtils.closeSession();
}
}
 Customer.hbm.xml
<hibernate-mapping package="com.haiersoft.ch05.pojos">
<class name="Custoemr" table="CUSTOMER">
... ...省略其它代码
<!-- 1-N关联关系 -->
<set name="orders" cascade="save-update">
<key column="CUSTOMER_ID"/>
<one-to-many class="Order"/>
</set>
</class>
</hibernate-mapping>

上述代码中,配置了级联保存或更新操作,当保存顾客对象时,会把其对应的订单对象级联保存。

当运行main方法时,Hibernate执行了以下几条SQL语句:
insert into CUSTOMER (USERNAME , PASSWORD , REALNAME , ADDRESS , MOBILE )
values(?,?,?,?,?)   ①
insert into ORDERS (ORDERNO , ORDERDATE , TOTAL , CUSTOMER_ID )
values(?,?,?,?)   ②
update ORDER set CUSTOMER_ID =?  where ID=?   ③
 
上述结果中,执行了两条insert语句和一条update语句。
Hibernate首先在CUSTOMER 表中插入一条记录(①),然后再往ORDERS表中插入一条没有customer参数的记录,也就是说,插入的这句中的参数CUSTOMER_ID是没有值的(②),那么就需要用到第三条update语句了,它会根据前两条语句的记录,从中获取得到CUSTOMER_ID、ORDERS表的ID值,然后给ORDERS表中的记录中的CUSTOMER_ID外键进行赋值(③)。从而完成两张表之间的关联关系。
 
小结:级联关系方便了我们对有关联关系的数据操作,有了Hibernate的级联,你只要把有级联关系的主动关联方包含了被关联方的对象,那么我们只要对主动方进行操作就可以了,至于被关联方的数据它自己会按着我们关联关系被处理。
也就是说,由上面的例子中Customer对象是主动关联方,而Order是被关联方。当需要想数据库插入一条Customer记录,并且还要把它相应的Order记录一并插入数据库中时,那么我们只需要把order对象添加到customer对象的orders属性中,并直接对customer进行操作就可以了,其中order对象并不需要传入Customer参数,也不需要手动的去操作order对象保存到数据库中,Hibernate会帮我们解决掉它。
 
2. 级联控制反转
在1-N关联关系中,通常讲控制权交给“N” 方,这可以在<set>元素中通过配置inverse属性来实现,当inverse=“true”时表示关联关系由对方维护。修改后的Customer.hbm.xml代码如下:
<!-- 配置控制反转 -->
<set name="orders" inverse="true" cascade="save-update">
<key column="CUSTOMER_ID" />
<one-to-many class="Order" />
</set>
通过上面的配置,设置将关联的控制权交给Order对象,所以在保存Customer对象前Order对象必须关联到该对象,如下代码:
 
 public class BusinessService{
public static void main(String[] args){
//添加客户和订单信息
Customer customer = new Customer("lisi","123","李四","青岛市","123123123");
Order order = new Order("3",new Date(),1000.0);
//建立关联关系,实现级联保存
customer.getOrders().add(order);
//order对象必须关联customer对象,inverse才起作用
order.setCustomer(customer); Transaction trans = session.beginTransaction();
session.save(customer);
trans.commit();
HibernateUtils.closeSession(); }
}

上述代码中,利用语句“order.setCustomer(customer)”实现了order到customer对象的关联,当运行main()方法时,Hibernate执行了以下两条insert语句。

insert into CUSTOMER (USERNAME , PASSWORD , REALNAME , ADDRESS , MOBILE )
values(?,?,?,?,?)   ①
insert into ORDERS (ORDERNO , ORDERDATE , TOTAL , CUSTOMER_ID )
values(?,?,?,?)   ②
小结:当将关联的控制权交给“N”方时,无需执行update语句就可以完成两个关联对象之间的级联操作。

级联关系(内容大部分来自JavaEE轻量型解决方案其余的是我的想法)的更多相关文章

  1. Raspkate - 基于.NET的可运行于树莓派的轻量型Web服务器

    最近在业余时间玩玩树莓派,刚开始的时候在树莓派里写一些基于wiringPi库的C语言程序来控制树莓派的GPIO引脚,从而控制LED发光二极管的闪烁,后来觉得,是不是可以使用HTML5+jQuery等流 ...

  2. 轻量型ORM框架Dapper的使用

    在真实的项目开发中,可能有些人比较喜欢写SQL语句,但是对于EF这种ORM框架比较排斥,那么轻量型的Dapper就是一个不错的选择,即让你写sql语句了,有进行了关系对象映射.其实对于EF吧,我说下我 ...

  3. 五款轻量型bug管理工具横向测评

    五款轻量型bug管理工具横向测评 最近正在使用的本地bug管理软件又出问题了,已经记不清这是第几次了,每次出现问题都要耗费大量的时间精力去网上寻找解决方案,劳心劳力.为了避免再次出现这样的情况,我决定 ...

  4. 实战ELK(4)Metricbeat 轻量型指标采集器

    一.介绍 用于从系统和服务收集指标.从 CPU 到内存,从 Redis 到 Nginx,Metricbeat 能够以一种轻量型的方式,输送各种系统和服务统计数据. 1.系统级监控,更简洁(轻量型指标采 ...

  5. Metricbeat 轻量型指标采集器

    一.介绍 用于从系统和服务收集指标.从 CPU 到内存,从 Redis 到 Nginx,Metricbeat 能够以一种轻量型的方式,输送各种系统和服务统计数据. 1.系统级监控,更简洁(轻量型指标采 ...

  6. 基于轻量型Web服务器Raspkate的RESTful API的实现

    在上一篇文章中,我们已经了解了Raspkate这一轻量型Web服务器,今天,我们再一起了解下如何基于Raspkate实现简单的RESTful API. 模块 首先让我们了解一下"模块&quo ...

  7. 利用Sharepoint 创建轻量型应用之基本功能配置!

    博客同步课程.假设你想跟着视频学习,请跟着例如以下视频: http://edu.csdn.net/course/detail/2097 1.   点击安装程序,出现的界面先期安装完毕准备工具,准备工具 ...

  8. .Net Core3.0 WebApi 项目框架搭建 五: 轻量型ORM+异步泛型仓储

    .Net Core3.0 WebApi 项目框架搭建:目录 SqlSugar介绍 SqlSugar是国人开发者开发的一款基于.NET的ORM框架,是可以运行在.NET 4.+ & .NET C ...

  9. Unslider – 轻量的响应式 jQuery 内容轮播插件

    Unslider 是一款非常轻量的 jQuery 插件(压缩后不到3KB),能够用于任何 HTML 内容的滑动. 可以响应容器的大小变化,自动排布不用大小的滑块.可以通过整合 jQuery.event ...

随机推荐

  1. 浅谈数据库系统中的cache(转)

    http://www.cnblogs.com/benshan/archive/2013/05/26/3099719.html 浅谈数据库系统中的cache(转)   Cache和Buffer是两个不同 ...

  2. [洛谷P2634][国家集训队]聪聪可可

    题目大意:给你一棵树,随机选两个点,求它们之间路径长度是$3$的倍数的概率 题解:点分治,求出当前状态的重心,然后求出经过重心的答案,接着分治每棵子树.注意考虑重复计算的情况 卡点:无 C++ Cod ...

  3. 《c程序设计语言》-3.2 字符串转换

    #include <stdio.h> #define Num 1000 int main() { int i = 0,j,k,count2 = 0; char s[Num] = {'\0' ...

  4. vue组件中使用iframe元素

    需要在本页面中展示vue组件中的超链接,地址栏不改变的方法: <template> <div class="accept-container"> <d ...

  5. 静态页面之间的转发与json与ajax做到动态数据

    我们见过很多使用jsp ,php,asp的动态网页技术的网站了,我们知道如果一个网站内容更新频率极低,而内容量不是十分庞大时,这样的网站(一次开发完成后不会需要较多的维护成本)的完全可以使用全部使用静 ...

  6. 汕头市队赛 SRM 08 C

    C-3 SRM 08 描述 给一个图,n 个点 m 条双向边,每条边有其长度.n 个点中有 k 个是特殊点,问任意两个特殊点的最短路是多少. 输入格式 第一行三个整数 n m k 第二行 k 个整数  ...

  7. Photoshop  cs6 快捷键命令大全

    工具箱(多种工具共用一个快捷键的可同时按[Shift]加此快捷键选取) 矩形.椭圆选框工具.单行单列选取工具 [M] 裁剪工具.透视.切片.透视裁剪工具 [C] 移动工具 [V] 套索.多边形套索.磁 ...

  8. fork+exec 与system,popen区别

    1.fork + exec fork用来创建一个子进程.一个程序一调用fork函数,系统就为一个新的进程准备了前述三个段,首先,系统让新的进程与旧的进程使用同一个代码段,因为它们的程序还是相同的,对于 ...

  9. 【转载】Java文件编码自动转换工具类

    本篇随笔主要介绍了一个用java语言写的将一个文件编码转换为另一个编码并不改变文件内容的工具类: 通过读取源文件内容,用URLEncoding重新编码解码的方式实现. 1 public class C ...

  10. visio画任意形状图形

    1,连接线--右击---曲线连接线 2,选中组合 3,开发工具--操作--连接--填充