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. Java分布式数据导出实践

    伴随业务发展日益剧增,对数据的要求越来越多也越来越高. 用户在浏览器发起导出请求--web服务器接收请求--请求后台获取数据--数据统计后生成excel或其他图标--响应给客户端 整个过程至少5步,才 ...

  2. BZOJ3594 [Scoi2014]方伯伯的玉米田 【树状数组优化dp】

    题目链接 BZOJ3594 题解 dp难题总是想不出来,, 首先要观察到一个很重要的性质,就是每次拔高一定是拔一段后缀 因为如果单独只拔前段的话,后面与前面的高度差距大了,不优反劣 然后很显然可以设出 ...

  3. IE6对!important单个的类是支持的

    "!important"是什么? 第一个,是设置样式的优先级,设了!important的样式的属性优先于id选择器和class选择器.,比如id为"Main"的 ...

  4. js加解密的算法

    //字符串和数字互转 var str="a" var r = str.charCodeAt(0); //97 10进制 console.log(r); var t=String.f ...

  5. theMatrix代码雨效果

    做了一个代码雨效果放在个人主页:  https://lanleilin.github.io/lanGallery/index.html 代码: <!DOCTYPE html> <ht ...

  6. 母函数(Generation Function) 入门 + 模板

    转自:母函数 入门 + 模板  感谢 在数学中,某个序列的母函数(Generating function,又称生成函数)是一种形式幂级数,其每一项的系数可以提供关于这个序列的信息.使用母函数解决问题的 ...

  7. 51nod1086 背包问题 V2——二进制优化

    有N种物品,每种物品的数量为C1,C2......Cn.从中任选若干件放在容量为W的背包里,每种物品的体积为W1,W2......Wn(Wi为整数),与之相对应的价值为P1,P2......Pn(Pi ...

  8. 日志组件Log4Net

    <?xml version="1.0" encoding="utf-8"?> <configuration> <configSec ...

  9. POCO库中文编程参考指南(4)Poco::Net::IPAddress

    POCO库中文编程参考指南(4)Poco::Net::IPAddress 作者:柳大·Poechant 博客:Blog.CSDN.net/Poechant 邮箱:zhongchao.ustc#gmai ...

  10. mysql中数据类型的长度

    这是一篇很全面的博客的网址 http://qimo601.iteye.com/blog/1622368 下图是其中一部分截图,在mysql数据库中新建数据表时有个长度的设置