数据库中的表一般都是相互关联的,它们通过foreign key产生关系。
定义foreign key约束时可以指定三种引用行为:delete cascade、delete set null、delete no action,默认是delete on action。它们的含义是:
1、delete cascade : 删除主表的同时也删除子表有关的记录
这个行为适合主从表关系较为紧密的情况,比如菜单和子菜单。当主表的记录不存在时,从表的数据已经没有意义,存在也是多余,所以当删除主表时,从表相关记录也一同删除。
2、delete set null : 删除主表时将子表外键设置为NULL
这个行为适合主从表关系不是相当密切的情况,比如角色和用户,一个角色可以对应多个用户(一个用户也可以有多重角色),不能因为删除了某个角色,而把属于这个角色的用户都删除了,因为这些用户可能还和其他表有很大关系。
3、delete no action: 不做任何操作
这个情况下,如果主表的某个记录已经被引用,删除这条记录会失败,主要提醒用户注意数据完整性。
以上3种情况在hibernate下如果实现呢?下面以多对一关联举例。
假设新闻与用户存在多对一关联
1、删除用户的同时也删除他发表的新闻
News映射文件:
<many-to-one name="editer" class="Account">
<column name="editer_id"></column>
</many-to-one>
Account映射文件:
<set name="news" lazy="true" cascade="delete" inverse="true">
<!-- 主键对应的关联表外键 -->
<key column=" editer_id"></key>
<!-- 关联表 -->
<one-to-many class="News"/>
</set>
2、删除用户时不删除他发表的新闻
其实新闻表除了保存用户ID外,我建议还保存用户的名字,多了一点数据冗余,但是在查询新闻时不用外连接用户表,而且在删除新闻时,虽然外键置NULL,但用户名还在,我们还能知道这新闻是谁发布的。
<set name="news" lazy="true" cascade="save-update" inverse="false">
<!-- 主键对应的关联表外键 -->
<key column=" editer_id"></key>
<!-- 关联表 -->
<one-to-many class="News"/>
</set>
注意以上的inverser=false
3、删除用户时不执行额外操作
只要在<set>中设置 cascade="none"
转自:http://blog.sina.com.cn/s/blog_5016113a0100lj9y.html
注意
以上情况只是一对多关系,对于多于多等关系还是有些区别的,比如我通过中间表映射的多对多关系,在没有设置cascade的情况下,删除记录时,也会主动删除中间表中的记录,如:
menu映射文件
<set name="roles" lazy="true" table="MenuRole" >
<!-- 主键对应的中间表的外键 -->
<key column="menu_id" />
<many-to-many class="Role" column="role_id"/>
</set>
删除菜单时,会主动从中间表menurole删除记录
转自:http://blog.sina.com.cn/s/blog_5016113a0100lj9y.html