Hibernate –级联示例(保存,更新,删除和删除孤立的孤儿)

级联是一项方便的功能,用于保存手动管理另一侧状态所需的代码行。

“ Cascade”关键字通常出现在集合映射上,以自动管理集合的状态。 在本教程中,此一对多示例将用于演示级联效果。

级联保存/更新示例

在此示例中,如果保存了“库存”,则其所有引用的“ stockDailyRecords”也应保存到数据库中。

1.没有保存更新级联

上一节中 ,如果要将“股票”及其引用的“ StockDailyRecord”保存到数据库中,则需要分别保存两者。

Stock stock = new Stock();
StockDailyRecord stockDailyRecords = new StockDailyRecord();
//set the stock and stockDailyRecords  data

stockDailyRecords.setStock(stock);        
stock.getStockDailyRecords().add(stockDailyRecords);

session.save(stock);
session.save(stockDailyRecords);

输出量

Hibernate: 
    insert into mkyong.stock (STOCK_CODE, STOCK_NAME) 
    values (?, ?)

Hibernate: 
    insert into mkyong.stock_daily_record
    (STOCK_ID, PRICE_OPEN, PRICE_CLOSE, PRICE_CHANGE, VOLUME, DATE) 
    values (?, ?, ?, ?, ?, ?)

2.使用保存更新级联

在“ stockDailyRecords 中声明了层叠=“保存更新”以启用保存更新层叠效果。

<!-- Stock.hbm.xml -->
<set name="stockDailyRecords" cascade="save-update" table="stock_daily_record"...>
      <key>
            <column name="STOCK_ID" not-null="true" />
      </key>
      <one-to-many class="com.mkyong.common.StockDailyRecord" />
</set>
Stock stock = new Stock();
StockDailyRecord stockDailyRecords = new StockDailyRecord();
//set the stock and stockDailyRecords  data

stockDailyRecords.setStock(stock);        
stock.getStockDailyRecords().add(stockDailyRecords);

session.save(stock);

输出量

Hibernate: 
    insert into mkyong.stock (STOCK_CODE, STOCK_NAME) 
    values (?, ?)

Hibernate: 
    insert into mkyong.stock_daily_record
    (STOCK_ID, PRICE_OPEN, PRICE_CLOSE, PRICE_CHANGE, VOLUME, DATE) 
    values (?, ?, ?, ?, ?, ?)

代码session.save(stockDailyRecords); 不再需要,当您保存“股票”时,它将“层叠”保存操作到其引用的“ stockDailyRecords”,并将两者自动保存到数据库中。

级联删除示例

在此示例中,如果删除了“股票”,则其所有引用的“ stockDailyRecords”也应从数据库中删除。

1.没有删除级联

您需要循环所有“ stockDailyRecords”并逐一删除。

Query q = session.createQuery("from Stock where stockCode = :stockCode ");
q.setParameter("stockCode", "4715");
Stock stock = (Stock)q.list().get(0);
    
for (StockDailyRecord sdr : stock.getStockDailyRecords()){
         session.delete(sdr);
}
 session.delete(stock);

输出量

Hibernate: 
    delete from mkyong.stock_daily_record 
    where DAILY_RECORD_ID=?

Hibernate: 
    delete from mkyong.stock 
    where STOCK_ID=?

2.带删除级联

在“ stockDailyRecords 中声明了级联=“删除”以启用删除级联效果。 当您删除“股票”时,其所有参考“ stockDailyRecords”将被自动删除。

<!-- Stock.hbm.xml -->
<set name="stockDailyRecords" cascade="delete" table="stock_daily_record" ...>
      <key>
            <column name="STOCK_ID" not-null="true" />
      </key>
      <one-to-many class="com.mkyong.common.StockDailyRecord" />
</set>
Query q = session.createQuery("from Stock where stockCode = :stockCode ");
q.setParameter("stockCode", "4715");
Stock stock = (Stock)q.list().get(0);
session.delete(stock);

输出量

Hibernate: 
    delete from mkyong.stock_daily_record 
    where DAILY_RECORD_ID=?

Hibernate: 
    delete from mkyong.stock 
    where STOCK_ID=?

级联删除孤儿示例

在上述层叠删除选项中,如果删除Stock,则其所有引用的“ stockDailyRecords”也将从数据库中删除。 如果您只想删除两个引用的“ stockDailyRecords”记录怎么办? 这称为孤立删除,请参见示例…

1.没有删除孤立级联

您需要一个一个地删除“ stockDailyRecords”。

StockDailyRecord sdr1 = (StockDailyRecord)session.get(StockDailyRecord.class, 
                                            new Integer(56));
StockDailyRecord sdr2 = (StockDailyRecord)session.get(StockDailyRecord.class, 
                                            new Integer(57));

session.delete(sdr1);
session.delete(sdr2);

输出量

Hibernate: 
    delete from mkyong.stock_daily_record 
    where DAILY_RECORD_ID=?
Hibernate: 
    delete from mkyong.stock_daily_record 
    where DAILY_RECORD_ID=?

2.使用delete-orphan级联

在“ stockDailyRecords 中声明了cascade =“ delete-orphan”以启用删除孤儿层叠效果。 当您保存或更新库存时,它将删除那些已标记为已删除的“ stockDailyRecords”。

<!-- Stock.hbm.xml -->
<set name="stockDailyRecords" cascade="delete-orphan" table="stock_daily_record" >
      <key>
            <column name="STOCK_ID" not-null="true" />
      </key>
      <one-to-many class="com.mkyong.common.StockDailyRecord" />
</set>
StockDailyRecord sdr1 = (StockDailyRecord)session.get(StockDailyRecord.class, 
                                       new Integer(56));
StockDailyRecord sdr2 = (StockDailyRecord)session.get(StockDailyRecord.class, 
                                       new Integer(57));

Stock stock = (Stock)session.get(Stock.class, new Integer(2));
stock.getStockDailyRecords().remove(sdr1);
stock.getStockDailyRecords().remove(sdr2);
		
session.saveOrUpdate(stock);

输出量

Hibernate: 
    delete from mkyong.stock_daily_record 
    where DAILY_RECORD_ID=?
Hibernate: 
    delete from mkyong.stock_daily_record 
    where DAILY_RECORD_ID=?

简而言之,delete-orphan允许父表删除其子表中的几个记录(删除孤子)。

如何启用级联?

XML映射文件和注释均支持级联。

1. XML映射文件

在XML映射文件中,在您的关系变量中声明了cascade关键字。

<!-- Stock.hbm.xml -->
<set name="stockDailyRecords" cascade="save-update, delete" 
        table="stock_daily_record" ...>
      <key>
            <column name="STOCK_ID" not-null="true" />
      </key>
      <one-to-many class="com.mkyong.common.StockDailyRecord" />
</set>

2.注释

在注释中,在@Cascade注释中声明CascadeType.SAVE_UPDATE (保存,更新)和CascadeType.REMOVE (删除)。

//Stock.java
        @OneToMany(mappedBy = "stock")
        @Cascade({CascadeType.SAVE_UPDATE, CascadeType.DELETE})
	public Set<StockDailyRecord> getStockDailyRecords() {
		return this.stockDailyRecords;
	}

进一步研究– 级联– JPA和Hibernate注释常见错误

逆与级联

两者是完全不同的概念,请参见此处区别

结论

级联是非常方便的功能,可以自动管理另一侧的状态。 但是,此功能带有价格,如果您不明智地使用它(更新或删除),它将生成许多不必要的级联效果(级联更新)以降低性能,或删除(级联删除)一些您没有使用的数据预期。

翻译自: https://mkyong.com/hibernate/hibernate-cascade-example-save-update-delete-and-delete-orphan/

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值