【问题标题】:How to delete entities using Criterion efficiently?如何有效地使用 Criterion 删除实体?
【发布时间】:2013-02-20 16:35:52
【问题描述】:

目前,我必须创建一个临时的Criteria 并使用Criteria.list() 获取匹配的实体列表,然后将列表传递给HibernateTemplate.deleteAll()

void delete(Criterion criterion) {
    Criteria c = DetachedCriteria.forClass(Foo.class).getExecutableCriteria(session);
    c.add(criterion);
    getHibernateTtemplate().deleteAll(c.list());
}

是否可以按标准删除但不首先加载列表?

也许,我应该将标准转换为 HQL,例如 "delete from Foo where " + criterion.toHQL()

背景

我有一个搜索表单,稍后会对其进行解析并转换为 Criteria 组合。

使用 Criteria.list() 检索搜索结果。

现在,出现了一个问题,我想删除所有搜索结果。我是否应该以不同的方式再次解析搜索表单以将其转换为 HQL 字符串?如果我可以重用 Criteria,事情会更简单。

由于 Criteria 最等同于 WHERE 子句,(不是吗?)我认为没有理由不能将 Criteria 用于删除。

【问题讨论】:

    标签: java performance hibernate optimization spring-orm


    【解决方案1】:

    您确实只能使用 HQL 来做到这一点。没有等效的标准 API。

    【讨论】:

    • 然后,我会坚持使用 list-and-delete,它确实有效,但速度很慢。
    • 为什么首选 Criteria API 而不是 HQL?
    • 因为我在本地项目中使用 Criteria 制作了大部分 API,以防止程序员做坏事。从一种组合(搜索表单)转换为另一种组合(标准)也感觉更好。
    【解决方案2】:

    我认为您可以使用 HibernateTemplate 类中的方法 execute(HibernateCallback action)。它可能看起来像这样:

    final Criterion criteria;
    HibernateTemplate template;
    template.execute(new HibernateCallback() {
        @Override
        public Object doInHibernate(Session session) throws HibernateException, SQLException {
            List toDelete = session.createCriteria(Student.class).add(criteria).list();
            for (Object o: toDelete){
                session.delete(o);
            }
        }
    });
    

    恕我直言,此解决方案效率不高,因为您必须在删除所有条目之前阅读它们。而且你必须单独删除每个条目,这是非常低效的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-21
      • 2021-12-20
      • 1970-01-01
      • 1970-01-01
      • 2012-09-26
      • 2012-08-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多