【发布时间】:2017-06-17 12:40:42
【问题描述】:
我有这样的要求。
protected Integer[] updateFullTable(final Class clazz){
final ProjectionList projectionList=Projections.projectionList().add(Projections.property("id"),"id");
final Criteria criteria=session.createCriteria(clazz)
.add(Restrictions.eq("typeOfOperation",1))
.add(Restrictions.eq("performUpdate",true));
criteria.setProjection(projectionList);
final List idsList=criteria.list();
final Integer[]ids = transformObjectArrayIntoIntegerArray(idList);
//NOW WE UPDATE THE ROWS IDS.
final Query query=session.createQuery("update "+clazz.getName()+" set activeRegister=true and updateTime=:updateTime where id in (:ids)")
.setParameter("updateTime",new Date())
.setParameterList("ids",ids);
query.executeUpdate();
return transform;
}
正如你们所看到的,有时我需要更新表中的所有行,我查询所有行 id,然后在单独的查询中将更新应用于这些 id,但表有时会有很多记录需要介于30 秒到 10 分钟取决于表。
我已将此代码更改为只有一个这样的更新。
final Query query=session.createQuery("update "+clazz.getName()+" set activeRegister=true and updateTime=:updateTime where typeOfOperation=1 and performUpdate=true");
通过唯一的查询,我避免了第一个查询,但我不能再返回受影响的 Id。但后来要求是改变一个
final StringBuilder logRevert;
已添加参数。
如果需要,需要存储更新后的 id 以将直接反向更新应用到数据库中。
但是随着我的更新,我无法再获得 ID。我的问题是如何使用存储过程或数据库或休眠中的一些解决方法获取或返回受影响的 id 我的意思是仅通过一个查询或增强代码获得第一个行为..
任何提示。
我试过了
- 使用标准
- 使用 HQL。
- 使用命名查询
- 使用 SqlQuery
- 不使用转换器返回原始 Object[]
但时代仍然有些高。
我想要类似的东西
query.executeUpdate(); // RETURNS THE COUNT OF THE AFFECTED ROWS
但我需要受影响的 ID……
对不起,如果问题很简单。
更新
使用@dmitry-senkovich,我可以使用 rawSQL 做到这一点,但不能使用 hibernate,这里提出了一个单独的问题。
https://stackoverflow.com/questions/44641851/java-hibernate-org-hibernate-exception-sqlgrammarexception-could-not-extract-re
【问题讨论】:
-
如果你想最小化资源使用和最大化性能,你必须使用游标或存储过程(它使用游标)如果你不关心浪费一些周期并且你的时钟是可靠的,您还可以更改算法以先进行更新。更新后,您可以在 where 子句中使用为行设置的时间戳获取 id