cascade与inverse分析笔记

在介绍cascade和inverse之前我们要明确一个问题,这两个xml属性标签,都是定义某个set集合(<set>)或是某个<many-to-one>标签的级联操作和关联维护关系的。因此也只有其做为属性的父类在操作这些属性时,它们才起作用。

cascade

例如:

<class name="Test1" table="Test1" >
<id name="id">
<generator class="increment" />
</id>
<set name="childs" cascade="save-update" inverse="true">
<key column="parentId"></key>
<one-to-many class="Test1" />
</set>

<many-to-one name="parent" column="parentId" class="Test1" />
<property name="name" />
</class>

以下是测试代码

Test1 test3 = new Test1();
test3.setName("test3");
Test1 test1 = (Test1) this.getTemplate().load(Test1.class, 1l);
test1.getChilds().add(test3);
   

这段代码执行完成后会生成一条insert语句

insert into Test1(id,name,parentId) values(?,?,?)

?=1,?=test3,?=null

为什么会产生一条insert语句,这是因为cascade=save-update的作用,如果主对象修改childs的集合(增或删集合内容,或修改了集合中某个对象的属性),则会相应的产生insert和update语句.如果我们设置cascade=none,还是上面的代码,则不会有这条insert语句生成.

如果cascade=save-update,delete或all,则下列代码将删除id=1,及其下的所有的子对象

Test1 test1 = (Test1) this.getTemplate().load(Test1.class, 1l);
this.getTemplate().delete(test1);
 

如果cascade=cascade="save-update,delete,delete-orphan",则下列代码将删除id=2的子对象,因为其已不是test1的子对象了(按照delete-orphan规则)

Test1 test1 = (Test1) this.getTemplate().load(Test1.class, 1l);
test1.getChilds().remove(this.getTemplate().load(Test1.class, 2l));
 

 

inverse

例如:

    <class name="Test1" table="Test1" >
        <id name="id">
            <generator class="increment" />
        </id>
        <set name="childs" cascade="save-update" inverse="false" >
            <key column="parentId"></key>
            <one-to-many class="Test1" />
        </set>

        <many-to-one name="parent" column="parentId" class="Test1" />
        <property name="name" />
    </class>

还是上面的java代码,执行完后会生成两条语句

insert into Test1 (parentId, name, id) values (?, ?, ?)
update Test1 set parentId=? where id=?

?1=null,?2=test3,?3=4

?4=1,?5=4

为什么会产生两句sql语句,因为inverse=false的作用,inverse=false的一段,是由主对象来维护关联关系,所以主对象只会修改其子对象的外键字段。

注意:第一条insert语句是cascade=save-update的作用产生的。

         第二条update语句是inverse=false作用产生的。两者没有任何关系。

如果还是上面的java代码,我们把inverse=true,则只会生成一条insert语句

insert into Test1(id,name,parentId) values(?,?,?)

?=1,?=test3,?=null

为什么parentId还是被设置为null,因为我们的java代码不对,inverse=true则表示将由子类端(childs)来维护外键关系.

如果我们把java代码修改成这样:

 
Test1 test3 = new Test1();
test3.setName("test3");
Test1 test1 = (Test1) this.getTemplate().load(Test1.class, 1l);
test1.getChilds().add(test3);
test3.setParent(test1);
 

会生成insert语句中将明确的会赋值parentId。因为test3.setParent(test1)使test3子对象知道了其父对象是谁.

即然是inverse=true,还有test3.setParent(test1);语句,那我们还要test1.getChilds().add(test3);语句做什么,其应该是没用的语句呀,这里如果你这样想,则忽略的一个问题,上面的代码是被一个hibernate的事务包围,在这段代码只有test1是持久性的,在hibernate事务处理后的清除语句(flush)中将只对持久化被修改的属性生成sql语句,这点很重要.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值