微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

我想在hibernate Hql中的同一查询中执行多个更新语句.
如下所示:
hql = " update Table1 set prob1=null where id=:id1; "
                + " delete from Table2 where id =:id2 ";
...
query.executeUpdate();

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

那可能吗?

解决方法

简而言之,您正在寻找的是像JDBC中的批处理. Thich不是由Hibernate提供的批量更新查询,我怀疑是否会被考虑用于Hibernate.

从我过去的经验来看,HQL的批处理功能在现实生活中很少有用.这可能听起来很奇怪,某些东西在sql JDBC中有用,但不在HQL中.我会尽力解释.

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

给出一个例子,在伪代码中:

在JDBC中,您可以执行以下操作(我正在尝试模拟您在exmaple中显示内容):

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批处理在flush()中执行DB CUD操作.更重要的是,这是ORM的全部目的:我们希望提供行为丰富的实体来处理,实体的内部状态变化可以“透明地”反映在持久存储中.

HQL批量更新目的在于其他用途,这就像DB的一个批量更新影响大量记录,例如:

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();

在这种使用情况下很少需要执行大量查询,因此,DB往返的开销是微不足道的,因此对批量更新查询的批处理支持的益处很少.

我不能忽略有些情况,您真的需要发布大量的更新查询,这不适合通过有意义的实体行为来完成.在这种情况下,您可能需要重新考虑Hibernate是否是正确使用的工具.您可以考虑在这种用例中使用纯JDBC,以便控制如何发出查询.

原文地址:https://www.jb51.cc/java/125034.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐