使用 JPA 更新多行

发布于 2024-09-30 18:09:19 字数 145 浏览 4 评论 0原文

我想更新列 NAME 值为“PCNAME”的表的所有字段。 我要更新的表名称是 XYZ。我只想更新某些字段而不保留某些字段不变。

这将影响许多行,而不是单行,因为会有许多行 NAME='PCNAME' 我如何使用 JPA 来做到这一点。我有与此表关联的实体类。

I want to update all fields of a table that has value of colum NAME as 'PCNAME'.
The table name which i want to update is XYZ.I want to update only some fields and not keep some unchanged.

This will affect many rows and not a single row as there will be many rows with NAME='PCNAME'
How can i do it using JPA.I have entity class associated with this table.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

爱给你人给你 2024-10-07 18:09:19

您可以采用面向对象的方式或使用更新查询来完成此操作。

面向对象:

public void setNameOfAllEntities(String newname){
    List<MyEntity> items =
        entityManager.createQuery("from MyEntity", MyEntity.class)
            .getResultList();
    for(MyEntity entity : items){
        entity.setName(newname);
    }
}

使用更新查询(未经测试):

public void setNameOfAllEntities(final String newname){

    final int changes =
        entityManager.createQuery("update MyEntity set name = :name")
            .setParameter("name", newname)
            .executeUpdate();

    System.out.println(changes + " rows changed");

}

显然,第二个版本性能更好。

You can either do it the object oriented way or using an update query.

Object oriented:

public void setNameOfAllEntities(String newname){
    List<MyEntity> items =
        entityManager.createQuery("from MyEntity", MyEntity.class)
            .getResultList();
    for(MyEntity entity : items){
        entity.setName(newname);
    }
}

With Update Query (untested):

public void setNameOfAllEntities(final String newname){

    final int changes =
        entityManager.createQuery("update MyEntity set name = :name")
            .setParameter("name", newname)
            .executeUpdate();

    System.out.println(changes + " rows changed");

}

Obviously, the second version performs better.

明明#如月 2024-10-07 18:09:19

Seanizer 的答案是正确的 (+1),批量更新将是对于这个用例来说确实很好。但您必须对批量更新操作采取一些预防措施。解释一下 JPA 规范:

  • 批量更新绕过乐观锁定检查(因此您必须手动增加版本列和/或根据需要手动验证版本列)
  • 持久化上下文不与批量操作的结果(因此批量操作应该在单独的事务中执行,或者在事务开始时、在加载可能受影响的任何实体的状态之前执行)。

因此,我的建议是至少增加版本列以避免与其他线程的并发问题:

UPDATE XYZ xyz
SET xyz.name = :newname, xyz.version = xyz.version + 1 

并在单独的事务中或在加载任何 XYZ 之前执行它,如前所述。

参考

  • JPA 1.0规范
    • 第 4.10 节“批量更新和删除操作”

seanizer's answer is correct (+1) and a bulk update would be indeed nice for this use case. But you must take some precautions with bulk update operations. To paraphrase the JPA specification:

  • bulk updates bypass optimistic locking checks (so you must manually increment the version column and/or manually validate the version column if desired)
  • the persistence context is not synced with the result of bulk operations (so bulk operations should be performed in a separate transaction or at the very beginning of a transaction, before loading the state of any entity that might be affected).

My suggestion would thus be to at least increment the version column to avoid concurrency problem with other threads:

UPDATE XYZ xyz
SET xyz.name = :newname, xyz.version = xyz.version + 1 

And to perform it in a separate transaction or before loading any XYZ as previously explained.

References

  • JPA 1.0 specification
    • Section 4.10 "Bulk Update and Delete Operations"
那些过往 2024-10-07 18:09:19

从 Java Persistence 2.1 开始,您可以使用 CriteriaUpdate< /code>使用 Criteria API 进行批量更新。

CriteriaUpdate<Entity> criteriaUpdate = builder.createCriteriaUpdate(Entity.class)
     .set(root.get("field"), value)
     .where(predicates);
int updated = entityManager.createQuery(criteriaUpdate).executeUpdate();

记住:

Criteria API 批量更新操作直接映射到数据库更新操作,绕过任何乐观锁定检查。如果需要,使用批量更新操作的便携式应用程序必须手动更新版本列的值,和/或手动验证版本列的值。持久化上下文与批量更新的结果不同步。

Since Java Persistence 2.1 you can use CriteriaUpdate to do bulk updates using the Criteria API.

CriteriaUpdate<Entity> criteriaUpdate = builder.createCriteriaUpdate(Entity.class)
     .set(root.get("field"), value)
     .where(predicates);
int updated = entityManager.createQuery(criteriaUpdate).executeUpdate();

Keep in mind:

Criteria API bulk update operations map directly to database update operations, bypassing any optimistic locking checks. Portable applications using bulk update operations must manually update the value of the version column, if desired, and/or manually validate the value of the version column. The persistence context is not synchronized with the result of the bulk update.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文