测试Hibernate中的三个属性:lazy,inverse,cascade

 

测试Hibernate中的三个属性:lazy,inverse,cascade

【测试环境】
一对多关系的两张表:boy、girl(一个男孩可以多个女朋友)

 boy表结构
 Field   Type        
 ------  ----------- 
 name    varchar(50)  pk
 age     varchar(50) 

 girl表结构
 Field   Type        
 ------  ----------- 
 name    varchar(50)  pk
 bf      varchar(50)  fk

 ER图

 

【保存时:Inverse与cascade】

 创建三个girl对象和一个boy对象,让这是三个girl都是boy的女朋友

  ---------创建对象的代码片段-----------
  Boy boy = new Boy("tom","23", null);

  Set girls = new HashSet();
  
  Girl g[] = new Girl[]{
                        new Girl("Alice1", boy),
                        new Girl("Alice2", boy),
                        new Girl("Alice3", boy)};
  girls.add(g[0]);
  girls.add(g[1]);
  girls.add(g[2]);
  
  boy.setGirls(girls);
 
 在Boy.hbm.xml中设置,然后对boy对象进行保存。

 1.Inverse = true,不指定cascade
   cascade的默认值为none, 当对boy进行保存操作时,girl什么都不做. 所以只保存了boy对象, 没有保存girl对象

 2.Inverse = true,cascade=all
   boy与girl对象,包扩外键都成功保存。
   (生成3条SELECT语句和4条INSERT语句,一下简称SELECT 3, INSERT 4)

 3.Inverse = false,不指定cascade
   报错。因为boy为主控方,负责维护关系,所以在插入boy对象后,会尝试修改并不存在的girl对象。

 4.Inverse = false,cascade=all
   boy与girl对象,包扩外键都成功保存。
   (SELECT 4, INSERT 4, UPDATE 3)

   分析:除了4条INSERT语句之外,其他的6条语句是我们为了图方便付出的代价:3条SELECT语句用来判断girl对象是否在数据表中已经存在,3条UPDATE语句是为了维护外键关系

 高效率的做法:在Boy.hbm.xml中设置Inverse=true,在Girl.hbm.xml中设置Inverse=false, cascade=all,然后保存三个girl对象
 (SELECT 1, INSERT 4)

   高效率的代价就是保存的时候比较麻烦

【删除时:Inverse与cascade】

 希望通过删除boy,也将3个girl对象删除。程序中先查出boy对象,然后进行删除
  -----------------------------------------
  Boy boy = (Boy) s.get(Boy.class, "tom");
  s.delete(boy);
  -----------------------------------------


 同样在Boy.hbm.xml中进行设置

 1.Inverse = true
   可以猜到结果是出错。原因:外键约束错误

 2.Inverse = false
   boy删除,girl表中外键变为null,没有删除记录
   (UPDATE 1, DELETE 1)

 3.Inverse = false, cascade = all
          全部删除
   (UPDATE 1, DELETE 4)

 4.Inverse = true, cascade = all
          全部删除
   (DELETE 4)

 

 

 
如果cascade属性的值为all-delete-orphan,表示如果中断关联关系,会将另一方的孤立记录(orphan)删除.
 
比如现在要修改boy对象,更换他的女朋友,像下面这么写:
 
    Boy boy = (Boy) s.get(Boy.class, "tom");
 
    boy.getGirls().clear();
是否会从girl表中删除原有的三条记录呢? 答案会随着inverse和cascade的设置不同而不同:
inverse = true, cascade = all  : girl表中的三条记录没有变化
inverse = false, cascade = all  : girl表中的三条记录外键会变为null,但是不会被删除
cascade = all-delete-orphan : girl表中的三条记录全部被删除
 
结论:当映射多对多关系时,主表和关系表之间应该设置cascade = all-delete-orphan,这样在修改关系时,可以删除旧的关系
 


 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值