Neb*_*ras 10 java mysql hibernate hql
我想在hibernate Hql中的同一个查询中执行多个更新语句.如下:
hql = " update Table1 set prob1=null where id=:id1; "
+ " delete from Table2 where id =:id2 ";
...
query.executeUpdate();
Run Code Online (Sandbox Code Playgroud)
在同一个executeUpdate
调用中,我想更新Table1中的记录并从Table2中删除记录.
那可能吗?
简而言之,您正在寻找类似于 JDBC 中的批处理的东西。Hibernate 没有为批量更新查询提供此功能,我怀疑 Hibernate 是否会考虑使用它。
根据我过去的经验,HQL 的批处理功能在现实生活中很少有用。有些东西在 SQL+JDBC 中有用,但在 HQL 中却没有,这听起来可能很奇怪。我会尽力解释。
通常,当我们使用 Hibernate(或其他类似的 ORM)时,我们是针对实体进行工作的。Hibernate 将负责将实体的状态与数据库同步,这在大多数情况下 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();
Run Code Online (Sandbox Code Playgroud)
从 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();
}
}
Run Code Online (Sandbox Code Playgroud)
我怀疑您认为您需要批处理功能,因为您正在做类似的事情(根据您的示例,您对单个记录使用批量更新)。但这不是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
Run Code Online (Sandbox Code Playgroud)
通过这样做,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();
Run Code Online (Sandbox Code Playgroud)
在这种使用场景中很少需要执行大量查询,因此数据库往返的开销微不足道,因此批量更新查询的好处和批处理支持很少显着。
我不能忽略的是,在某些情况下,您确实需要发出大量更新查询,而这不适合通过有意义的实体行为来完成。在这种情况下,您可能需要重新考虑 Hibernate 是否是正确的工具。在这种用例中,您可以考虑使用纯 JDBC,以便您可以控制查询的发出方式。
归档时间: |
|
查看次数: |
19564 次 |
最近记录: |