使用 HQL 查询的 Hibernate 批量更新
Posted
技术标签:
【中文标题】使用 HQL 查询的 Hibernate 批量更新【英文标题】:Hibernate batch update using HQL Query 【发布时间】:2016-08-12 12:12:53 【问题描述】:我将 Hibernate 用于我的 ORM 层。 我尝试在一个事务中运行一批 HQL 查询(我不能使用 session.update)。 问题是即使 transaction.commit() 处于循环末尾,更新查询也会一一运行。 有没有办法在一个事务中运行多个 HQL 查询?
public void updateItems()
t = session.beginTransaction();
for (int i = 0; i < itemList.size(); i++)
Query q = createUpdateQuery(session, itemList.get(i));
q.executeUpdate(); //updating one by one, and not waiting for transaction commit
t.commit();
Query createUpdateQuery(Session session, Item item)
Query q = session.createQuery(
"Update Item i set i.notes=:notes, i.time=:time, i.counter=:counter, i.status=:status Where i.id=:id and i.time=:time");
q.setParameter("time", item.getTime());
q.setParameter("status", item.getStatus());
q.setParameter("notes", item.getNotes());
q.setParameter("id", item.getId());
return q;
感谢任何帮助。
【问题讨论】:
我看不出您的代码有任何明显错误。更新将一一发生在数据库上,但在您调用 commit 之前不会提交。您应该能够在调用提交之前随时回滚事务。这是相当标准的。您只是担心数据库的往返次数吗? 拥有一个事务并不意味着大批量发送多个更新。而且您的方法中有太多看起来不正确的事情(我希望这是您在生产代码中要做的)。 感谢您的回复。我需要从 session.update(item) 更改为这种方法,并且性能有所下降。 在我看来,您使用 Hibernate 的方式不合适。您应该更早地打开事务(可能围绕整个业务服务),获取您的实体,直接更新实体,并在提交 txn 时让 Hibernate 处理更新。通过这样做,通过适当的批量大小设置,Hibernate 将意识到多个相同类型的实体被更新,并利用 JDBC 批量操作来更新 DB 中的多条记录,从而减少往返次数。 【参考方案1】:您正在使用数据库事务来注册所有语句,但我认为您想使用batch updates。
只需添加以下配置属性:
<property name="hibernate.jdbc.batch_size" value="10"/>
即便如此,我认为您应该使用 Hibernate 来管理插入/更新/删除语句,因为您应该只关注entity state transitions。 dirty checking mechanism可以自动检测实体被修改,Hibernate可以为你生成更新语句,方便很多。
【讨论】:
以上是关于使用 HQL 查询的 Hibernate 批量更新的主要内容,如果未能解决你的问题,请参考以下文章