使用 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 批量更新的主要内容,如果未能解决你的问题,请参考以下文章

Hibernate批量处理数据HQL连接查询

Hibernate的批量查询

Hibernate框架学习——批量查询(概述)

转: Hibernate HQL查询 插入 更新(update)实例

Hibernate批量操作

Hibernate HQL查询 插入 更新(update)实例