数据库里的cascade的用法,Mysql和Hibernate里面是不相同。sql
在数据库里,进行增长、修改、删除记录的时候,常常会涉及到父子关系的表。
例如:有省份表和城市表,其中城市表有一个外键province_id引用到省份表的主键。这样,能够把省份表当作是父表,把城市表当作是子表,城市表记录的存在依赖于省份表的记录。(文中提到的例子,全部的代码在附件里都有,因此这里的描述从简)
1、在MySQL里的cascade
如下直接在MySQL的控制台操做省份表和城市表
在省份表增长一条“广东”的记录,在城市表增长一条“广州”的记录,而且把“广州”的外键引用到“广东”的主键。“广州”的存在依赖于“广东”,若是删除省份表的“广东”,将会影响到城市表的“广州”。根据城市表的外键约束的on delete设置,有以下三种状况:
一、外键没有on delete的设置:当删除“广东”的时候,MySQL会报错,删除失败。
二、外键设置为on delete cascade:当删除“广东”的时候,同时把“广州”也删除。
三、外键设置为on delete set null:当删除“广东”的时候,“广州”的外键province_id会被自动设置为null,即“广州”脱离了对“广东”的依赖关系。
2、在Hibernate里的cascade
如下用Hibernate来操做省份表和城市表
首先,在hibernate.cfg.xml文件配置好链接MySQL数据库的相关属性(请在那里修改登录数据库的密码)。而后,为省份表和城市表添加相关的POJO类和XML映射文件。用SQL语句建表(在附件的test_cascade.sql里),城市表有一个外键province_id引用到省份表的主键,并把这个外键设置为on delete cascade。这个外键约束,在Hibernate变成了双向的映射关系:City类有一个类型为Province的province属性,关联到省份表,在映射文件中是many-to-one的关系;Province类有一个Set<City>的cities属性,关联到城市表,在映射文件中是one-to-many的关系。
在Hibernate的映射文件里,一样能够设置cascade属性来控制父子关系。一般在父表设置cascade属性,有如下几种状况:
一、没有设置cascade属性
用方法addInNoCascade()增长记录“广东”和“广州”(方法在类CityManager里,如下同),再用方法delete()删除“广东”,将会出现异常,系统会说由于“广东”被城市表外键关联了而不能删除。用SQL建表时,已经把外键设为on delete cascade,怎么不能把“广东”删除的同时,级联删除“广州”呢?用MyEclipse查看城市表,发现有两个外键,如图所示:
第2个外键是用SQL建表时生成的,设置了on delete cascade;而第1个外键应该是用Hibernate操做数据库时,Hibernate自动创建的。第1个外键的On delete被设置为No action,所以删除“广东”的时候,受到这个外键的限制,致使删除失败。
二、设置cascade属性为delete-orphan
在映射文件Province.hbm.xml中,在one-to-many关系对应的Set里,设置cascade="delete-orphan",此功能与MySQL里设置外键设置为on delete cascade相同。再用方法delete()删除“广东”,删除成功。便是,设置cascade为delete-orphan之后,对删除父表记录的时候,会同时删除子表的相关记录。
三、设置cascade属性为all
cascade的属性,除了能够是delete-orphan,还能够是create、update、delete、all等等。all表明除 delete-orphan之外的全部属性值,当设置cascade为all之后,对父表记录的增长、修改操做,会影响到子表的相关记录。
在映射文件Province.hbm.xml中,在one-to-many关系对应的Set里,设置cascade="all"。用方法 addInCascadeOfAll()增长记录“广东”,方法里只有save“广东”,并无save“深圳”,只是用属性关联了“广东”和“深圳”的关系。结果显示,深圳也被添加到数据库里,这就是cascade="all"的做用,使对父表的操做影响到子表。
注意:A、delete-orphan是一个特别的属性值,只能应用在one-to-many关系的cascade属性。B、cascade属性一般在one-to-one和one-to-many关系里应用,不推荐在many-to-one或者many-to- many关系里应用。
3、总结
一、MySQL里设置cascade和在Hibernate设置cascade是不一样的。在MySQL里设置了cascade,并不能对Hibernate的操做起到做用,缘由是Hibernate自动为子表添加了外键。
数据库
二、使用级联(cascade)功能,方便了数据库的操做,使得操做一个表的记录会影响到其余表的记录。可是,级联功能会带来安全隐患。特别是在 Hibernate里,修改一个POJO对象的映射引用属性,会致使该引用属性所对应的POJO对象受到影响。例如,把“广东”的 Set<City>类型的cities属性清空(即对集合Set调用clear()方法),则会致使把引用“广东”的“深圳”删除了。所以,使用级联功能时要当心谨慎。安全
原文地址:不详。spa