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

前端之家收集整理的这篇文章主要介绍了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,以便控制如何发出查询.

猜你在找的Java相关文章