hibernate 父子表级联删除的两种应用情景
应用情景一:在数据库中设置主外键约束,并且设置数据库的删除级联。
然后在hibernate中的one-to-many设置inverse=true,cascade=all-delete-orphan
如:
<set name="news" cascade="all-delete-orphan" inverse="true">
<key column="TYPEID"/>
<one-to-many class="com.model.News"/>
</set>
在many-to-one端设置insert="false" update="false"
如:
<many-to-one name="newstype" column="TYPEID" entity-name="com.model.Newstype" insert="false" update="false"/>
这样可以实现级联删除。
这种方式可以有外键约束,另外在抛弃hibernate时也比较方便,与hibernate的耦合不是很紧密。
应用情景二:数据库中不作任何外键约束,数据库也不设置删除级联。可以这么理解,从数据库的角度出发,父子表没人任何关系,而如果有关系,那也
是建立在hibernate的定义文件中。
在hibernate中的one-to-many设置cascade=all(当然也可以设置cascade=delete),
在many-to-one保持默认。
比如在级联删除A(主表),和B(子表)时,
假如a中的一条记录有n条子表的记录
将有如下SQL产生:
Update B set a的主键的那个字段 = null
delete B1
delete B2
....
delete Bn
delete A
如:
Hibernate: update book set author=null where author=?
Hibernate: delete from user_role where id=?
Hibernate: delete from user_role where id=?
Hibernate: delete from user_role where id=?
Hibernate: delete from user_role where id=?
......
Hibernate: delete from user_role where id=?
Hibernate: delete from user where userId=?
即首先把b表的外键置为空,然后删除a表和b表,这就要求b表的外键可以允许为空
这种方式执行的SQL脚本数比较多,而且在数据模型中不能很好的反应父子表的一些约束关系。
因此我个人还是倾向于第一种方式。