Kev*_*ave 6 java hibernate hql where jpql
我发现JPA不支持以下更新:
Update Person p set p.name = :name_1 where p.id = :id_1,
p.name = :name_2 where p.id = :id_2,
p.name = :name_3 where p.id = :id_3
....
// It could go on, depending on the size of the input. Could be in 100s
Run Code Online (Sandbox Code Playgroud)
所以我有两个选择:
选项1:
Query q = em.createQuery("Update Person p set p.name = :name where p.id = :id");
For ( int x=0; PersonsList.length; x++ ) {
// add name and id parameters
em.executeUpdate();
}
Run Code Online (Sandbox Code Playgroud)
问题:
hibernate.jdbc.batch_size", "20"选项2:
使用Select Case语法或使用构造一个查询Criteria API
问题:
您可以更新对象列表,而无需迭代所有集合。
List<Integer> demo = Arrays.asList(1,2,3,4);
final String update = "UPDATE User u SET u.enabled = true WHERE u.id IN (?1)";
return super.getEntityManager()
.createQuery(update)
.setParameter(1, ids)
.executeUpdate();
Run Code Online (Sandbox Code Playgroud)
在您的问题标题中,您提到了批量更新和删除,但这次您实际上需要批处理。
当您想要更新/删除所有匹配可以在 WHERE 子句中表达的相同过滤条件的行时,需要批量更新和删除。
在这里,您需要 JDBC 批量更新。您需要设置以下配置属性:
<property name="hibernate.jdbc.batch_size" value="50"/>
Run Code Online (Sandbox Code Playgroud)
如果你这样做,你可以简单地更新实体,Hibernate 会为你批处理 UPDATE 语句。
选项 1不是很有用,因为它会生成 N 个无法批处理的 UPDATE 语句。
选项 2也不是很有用,因为它会生成一个非常复杂的查询,其执行计划可能比在简单的批处理 UPDATE 语句中执行所有内容更复杂。
所以,这样做:
如果您有很多这样的实体,请使用查询分页。
使用批量更新时,Hibernate 不会
version像常规实体更新那样自动递增用于乐观锁定的列,因此您需要显式递增version实体属性。
如果您要使用批处理,请参阅hibernate 文档的本章
与查询优化相比,batch_size 更多的是内存优化,查询保持不变,但您也可以通过充分利用内存来最小化往返。您需要每N次flush()和clear(),具体取决于batch_size的设置。
但仍然。。
1 条语句中的更新比多条语句中的更新快得多,因此如果您:
那么你可以考虑只创建原生查询而不是hql。