Hibernate 级联删除 和 hql编程实现删除 的比较

本文探讨了Hibernate级联删除和HQL编程实现删除两种方式。级联删除涉及多条SQL,先删除子实体再删除父实体,而HQL删除则更为简洁,仅需两条SQL。在选择时需要考虑是否需要额外加载关联数据,以避免懒加载异常。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

需求

在删除页面的同时,删除相对应的问题

实体关联关系:

这里写图片描述


方案一(Hibernate 级联删除):

  • 页面类(一方)的Page.hbm.xml的配置
<set name="questions" inverse="true"  cascade="delete" order-by="id" lazy="false"><!--[1]-->
    <key column="pageid"></key>
    <one-to-many class="Question"/>
</set>
        **关键点**:cascade="delete"  和  lazy="false"
  • 主要删除方法代码
@Test
public void deletePageByCasecade(){
    SurveyService ss = (SurveyService) ac.getBean("surveyService");
    Page page = ss.getPage(1);
    //当然这里还可以优化下,即 在 [1] 处配置 fetch="join" ,一条sql 得到 page 和 包含的 questions
    ss.deletePageCaseCade(page);
}
  • 生成 sql 语句

hibernate 先要得到 page 和相应的 question 记录

Hibernate: 

    select
       *
    from
        pages page0_ 
    where
        page0_.id=?
Hibernate: 
    select
        *
    from
        questions questions0_ 
    where
        questions0_.pageid=? 
    order by
        questions0_.id

然后 根据 questions 的 主键 一个一个的删除(而不是根据外间 pageid),即,page 中有多少个问题,便执行多少条 sql

Hibernate: 
    delete 
    from
        questions 
    where
        id=?
Hibernate: 
    delete 
    from
        questions 
    where
        id=?
Hibernate: 
    delete 
    from
        questions 
    where
        id=?
Hibernate: 
    delete 
    from
        questions 
    where
        id=?
 ...

最后删除 页面类(一方)

Hibernate: 
    delete 
    from
        pages 
    where
        id=?

小结
hibernate 的级联删除:
先查询,
再删除:先删除多方(孩子),再删除一方(父),按主键一个一个删除。
如果一个页面包含100个问题,就要执行 1+100 条删除语句


方案二(hql编程实现删除):

  • 主要删除方法代码
@Test
public void deletePageByHql(){
    SurveyService ss = (SurveyService) ac.getBean("surveyService");
    ss.deletePage(6);
}


    /*主要代码*/
    service 层
    public void deletePage(Integer pid) {

        //answer
        //String hql="delete from Answer a where a.questionId in ( select q.id from Question q where q.page.id=? )";
        //this.answerDao.batchEntityByHQL(hql, pid);

        //question
        hql="delete from Question q where q.page.id=?";
        this.questionDao.batchEntityByHQL(hql, pid);
        //page
        hql="delete from Page p where p.id=?";
        this.pageDao.batchEntityByHQL(hql, pid);
    }

    dao 层
    public void batchEntityByHQL(String hql, Object... objects) {

        Query query = sf.getCurrentSession().createQuery(hql);
        int len=objects.length;
        for(int i=0;i<len;i++){
            query.setParameter(i, objects[i]);
        }
        query.executeUpdate();
    }
  • 生成 sql 语句

两条语句即可

    Hibernate: 
        delete 
        from
            questions 
        where
            pageid=?
    Hibernate: 
        delete 
        from
            pages 
        where
            id=?

结论:

  • 方案一(Hibernate 级联删除 ):

    1. sql 语句太多
    2. page.hbm.xml 的配置 lazy=”false”/fetch=”join” ,查询 page 会自动加载(实例化) questions 集合。这个是不错,可是当我只想要查询 单个 page 的时候,就不太好了
  • 方案二( hql编程实现删除 ):

    1. sql 语句少
    2. page.hbm.xml 不用配置 lazy=”false”/fetch=”join”,查询page ,是单个page;如果需要在页面显示问题,一定要注意编码实现查询 page 的时候,实例化questions 集合,不然会有懒加载异常。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值