如何执行以 List 作为参数值的 JPA 批量更新语句
How to execute a JPA Bulk Update statement which takes a List as a parameter value
我有一个如下所示的更新查询
UPDATE
table_name
SET
column_name = ?
WHERE
column_name = ? AND id in (?)
所以 JPA 事务是
em.createNativeQuery(Update_QUERY)
.setParameter(1, updatedStatus)
.setParameter(2, currentStatus)
.setParameter(3, ids)
.executeUpdate();
该方法的输入是 List id、currentStatus 和 updatedStatus
如何将列表作为单个参数传递,如果我将列表转换为逗号分隔的字符串,我会收到错误指定的文本不是数字,因为 In 子句中不允许使用字符串。
How do I pass the List as a single parameter
示例方法:
String jpql = "UPDATE NameEntity ne " +
"SET ne.valstring = :updated_status " +
"WHERE ne.valstring = :current_status AND ne.id IN :ids";
em.createQuery(jqpl)
.setParameter("updated_status", updatedStatus)
.setParameter("current_status", currentstatus)
.setParameter("ids", Arrays.asList(ids))
.executeUpdate();
三个简单的规则:
使用本机 SQL 在 table 上 未 映射到实体的批量更新/删除。
本机 SQL 查询直接在数据库 table 上工作,绕过持久性上下文(一组托管实体),因此如果给定数据库 table没有对应实体
使用 JPQL 批量更新/删除 table 映射到实体
如果给定的数据库 table 被实体映射,使用 SQL 更新/删除将导致持久性上下文和底层数据库之间的不一致,因此请改用 JQPL 对应项,并且持久性提供程序将负责一致性。
批量更新/删除应该作为事务中的第一个操作执行,或者最好在它自己的事务中执行。
设置列表参数
接受 Object
参数的 JPA Query
interface setParameter
方法:
Query setParameter(String name, Object value)
可以取一个List
作为参数值。
这对 JPQL、条件 API 或批量更新和删除查询的工作方式相同:
List<Post> posts = entityManager.createNativeQuery("""
UPDATE
post
SET
status = :newStatus
WHERE
status = :oldStatus AND
id IN :ids
""", Post.class)
.setParameter("oldStatus", PostStatus.PENDING)
.setParameter("newStatus", PostStatus.APPROVED)
.setParameter("ids", List.of(1L, 2L, 3L))
.executeUpdate();
For more details about executing bulk update and delete statements with JPA and Hibernate, check out this article as well.
我有一个如下所示的更新查询
UPDATE
table_name
SET
column_name = ?
WHERE
column_name = ? AND id in (?)
所以 JPA 事务是
em.createNativeQuery(Update_QUERY)
.setParameter(1, updatedStatus)
.setParameter(2, currentStatus)
.setParameter(3, ids)
.executeUpdate();
该方法的输入是 List id、currentStatus 和 updatedStatus
如何将列表作为单个参数传递,如果我将列表转换为逗号分隔的字符串,我会收到错误指定的文本不是数字,因为 In 子句中不允许使用字符串。
How do I pass the List as a single parameter
示例方法:
String jpql = "UPDATE NameEntity ne " +
"SET ne.valstring = :updated_status " +
"WHERE ne.valstring = :current_status AND ne.id IN :ids";
em.createQuery(jqpl)
.setParameter("updated_status", updatedStatus)
.setParameter("current_status", currentstatus)
.setParameter("ids", Arrays.asList(ids))
.executeUpdate();
三个简单的规则:
使用本机 SQL 在 table 上 未 映射到实体的批量更新/删除。
本机 SQL 查询直接在数据库 table 上工作,绕过持久性上下文(一组托管实体),因此如果给定数据库 table没有对应实体
使用 JPQL 批量更新/删除 table 映射到实体
如果给定的数据库 table 被实体映射,使用 SQL 更新/删除将导致持久性上下文和底层数据库之间的不一致,因此请改用 JQPL 对应项,并且持久性提供程序将负责一致性。
批量更新/删除应该作为事务中的第一个操作执行,或者最好在它自己的事务中执行。
设置列表参数
接受 Object
参数的 JPA Query
interface setParameter
方法:
Query setParameter(String name, Object value)
可以取一个List
作为参数值。
这对 JPQL、条件 API 或批量更新和删除查询的工作方式相同:
List<Post> posts = entityManager.createNativeQuery("""
UPDATE
post
SET
status = :newStatus
WHERE
status = :oldStatus AND
id IN :ids
""", Post.class)
.setParameter("oldStatus", PostStatus.PENDING)
.setParameter("newStatus", PostStatus.APPROVED)
.setParameter("ids", List.of(1L, 2L, 3L))
.executeUpdate();
For more details about executing bulk update and delete statements with JPA and Hibernate, check out this article as well.