我有这样的要求。
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,或者在数据库或休眠中使用某些解决方法我的意思是只使用一个查询或增强的代码来获取第一个行为。
任何提示。
我试过了
但时间仍然有点高。
我想要像
这样的东西query.executeUpdate(); // RETURNS THE COUNT OF THE AFFECTED ROWS
但我需要受影响的Ids ......
很抱歉,问题很简单。
更新
使用@dmitry-senkovich,我可以使用rawSQL来实现,但不能使用hibernate,这里有一个单独的问题。
https://stackoverflow.com/questions/44641851/java-hibernate-org-hibernate-exception-sqlgrammarexception-could-not-extract-re
答案 0 :(得分:4)
以下解决方案如何?
SET @ids = NULL;
UPDATE SOME_TABLE
SET activeRegister = true, updateTime = :updateTime
WHERE typeOfOperation = 1 and performUpdate = true
AND (SELECT @ids := CONCAT_WS(',', id, @ids));
SELECT @ids;
答案 1 :(得分:1)
如果 updateTime 是datetime 您可以使用选择
选择所有受影响的记录ID Date updateTime = new Date(); // time from update
select id from clazz.getName() where updateTime=:updateTime and activeRegister=true and typeOfOperation=1 and performUpdate=true
答案 2 :(得分:1)
更新表中的大量行是一种缓慢的操作。这是因为需要抓住“老人”。在ROLLBACK
的情况下每行的值(由于显式ROLLBACK
,UPDATE
失败,同一事务中的失败或后续查询,或UPDATE
完成之前的电源故障)。
通常的解决方法是重新考虑需要大UPDATE
的应用程序设计。
另一方面,有一个可能的修复架构。请提供SHOW CREATE TABLE
,这样我就不必做太多的手挥动'在以下段落中......
可能更好地将需要更新的列移动到单独的并行表中("垂直分区")。如果
,这可能TEXT
,BLOB
等) - 不必制作庞大的副本。SELECT
点击未更新的列 - 避免某些其他阻止。 您仍然可以通过JOINing
两个表格获得原始列集。