当前位置: 首页 > 面试题库 >

Hibernate HQL,在同一查询中执行多个更新语句

苗运珧
2023-03-14
问题内容

我想在hibernateHql的同一查询中执行多个更新语句。如下所示:

hql = " update Table1 set prob1=null where id=:id1; "
                + " delete from Table2 where id =:id2 ";
...
query.executeUpdate();

在同一executeUpdate调用中,我想更新表1中的记录并从表2中删除记录。

那可能吗?


问题答案:

简而言之,您所看到的就像是JDBC中的批处理。Hichnate没有为批量更新查询提供Thich,并且我怀疑是否会为Hibernate考虑它。

根据我过去的经验,HQL的批处理功能在现实生活中很少有用。在SQL + JDBC中有用但在HQL中没有用的听起来很奇怪。我会尽力解释。

通常,当我们使用Hibernate(或其他类似的ORM)时,我们会与实体打交道。Hibernate将负责将我们实体的状态与DB同步,这在大多数情况下JDBC批处理可以帮助提高性能。但是,在Hibernate中,我们不通过批量更新查询来更改单个实体的状态。

只是举一个例子,用伪代码:

在JDBC中,您可以执行以下操作(我试图模仿您在示例中显示的内容):

List<Order> orders = findOrderByUserId(userName);
for (Order order: orders) {
    if (order outstanding quantity is 0) {
        dbConn.addBatch("update ORDER set STATE='C' where ID=:id", order.id);
    } else if (order is after expriation time) {
        dbConn.addBatch("delete ORDER where ID=:id", order.id);
    }
}
dbConn.executeBatch();

从JDBC逻辑到Hibernate的天真的转换可能会给你这样的东西:

List<Order> orders = findOrderByUserId(userName);
for (Order order: orders) {
    if (order outstanding quantity is 0) {
        q = session.createQuery("update Order set state='C' where id=:id");
        q.setParameter("id", order.id);
        q.executeUpdate();
    } else if (order is after expriation time) {
        q = session.createQuery("delete Order where id=:id");
        q.setParameter("id", order.id);
        q.executeUpdate();
    }
}

我怀疑您认为您需要批处理功能,因为您正在做类似的事情(根据您的示例,您对单个记录使用批量更新)。但是在Hibernate / JPA中 不是
应该怎么做的

(实际上最好通过存储库包装持久层访问,这里我只是简化图片)

List<Order> orders = findOrderByUserId(userName);
for (Order order: orders) {
    if (order.anyOutstanding()) {
        order.complete();    // which internally update the state
    } else if (order.expired) {
        session.delete(order);
    }
}

session.flush();   // or you may simply leave it to flush automatically before txn commit

这样,Hibernate具有足够的智能来检测已更改/已删除/已插入的实体,并利用JDBC批处理在处执行DB
CUD操作flush()。更重要的是,这是ORM的全部目的:我们希望提供行为丰富的实体以供使用,对于它们,实体的内部状态更改可以“透明地”反映在持久性存储中。

HQL批量更新旨在用于其他用途,这类似于对数据库的一次批量更新会影响很多记录,例如:

q = session.createQuery("update Order set state='C' " 
                        + " where user.id=:user_id "
                        + " and outstandingQty = 0 and state != 'C' ");
q.setParameter("user_id", userId);
q.executeUpdate();

在这种使用情况下,几乎不需要执行很多查询,因此,数据库往返的开销微不足道,因此,对批量更新查询的好处和批处理支持很少。

我不能忽略某些情况,您确实需要发出很多更新查询,而这些查询不适合有意义的实体行为来完成。在这种情况下,您可能需要重新考虑Hibernate是否是正确的工具。您可以考虑在这种用例中使用纯JDBC,这样您就可以控制如何发出查询。



 类似资料:
  • 问题内容: 我想知道是否可以使用JDBC执行类似的操作,因为即使在MySQL查询浏览器中,它当前也提供了异常。 虽然我确实意识到可以拆分SQL查询字符串并执行两次语句,但是我想知道是否有一次性的方法。 问题答案: 我想知道是否可以使用JDBC执行类似的操作。 对的,这是可能的。据我所知,有两种方法。他们是 通过设置数据库连接属性以允许多个查询,默认情况下用分号分隔。 通过调用返回隐式游标的存储过程

  • 问题内容: 我试图了解如何用不同的值更新多行,但我不明白。解决方案无处不在,但对我来说似乎很难理解。 例如,将三个更新更新为1个查询: 我读了一个例子,但我真的不明白如何进行查询。即: 如果在WHERE和IF条件中存在多个条件,我还不太清楚如何执行查询。 问题答案: 您可以这样操作: 我不了解您的日期格式。日期应使用本机日期和时间类型存储在数据库中。

  • 问题内容: 我在这里找到了一些可以更新一个字段的东西:http : //www.karlrixon.co.uk/articles/sql/update-multiple-rows-with-different- values-and-a-single-sql- query/ 我的问题是如何更新多个字段?如: 这当然是行不通的。尝试了其他几种组合并失败了。任何的想法?谢谢! 问题答案:

  • 我尝试通过实现以下函数,使用单个查询更新多行(约 350000): 尝试运行上述函数时,仅更新了 31 条记录。然后,我尝试使用以下函数逐行更新: 后者迄今已更新了所有记录,但速度很慢(估计将在9小时内结束)。有人知道更新多个记录的有效方法吗?

  • 我想知道是否可以在一个准备好的语句中执行多个SQL查询。这是我要执行的第一个查询: