Java Hibernate关于更新所有表字段性能的提示

Java Hibernate关于更新所有表字段性能的提示,java,mysql,hibernate,Java,Mysql,Hibernate,我有这样的要求 protected Integer[] updateFullTable(final Class clazz){ final ProjectionList projectionList=Projections.projectionList().add(Projections.property("id"),"id"); final Criteria criteria=session.createCriteria(clazz) .add(Restrictions

我有这样的要求

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;
}
final Query query=session.createQuery("update "+clazz.getName()+" set activeRegister=true and updateTime=:updateTime where typeOfOperation=1 and performUpdate=true");
正如你们看到的,我需要更新表中的所有行,有时我查询所有行ID,然后在单独的查询中将更新应用到这些ID,但表中有很多记录,有时需要30秒到10分钟,具体取决于表

我已将此代码更改为只有一个这样的更新

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;
}
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了。我的问题是如何使用存储过程或DB或hibernate中的一些解决方法获取或返回受影响的ID我的意思是仅使用一个查询或增强的代码获取第一个行为

任何小费

我试过了

使用标准 使用HQL。 使用namedQuery 使用SqlQuery 不使用transformer返回原始对象[] 但不知何故,时代仍然很高

我想要像这样的东西

query.executeUpdate();   // RETURNS THE COUNT OF THE AFFECTED ROWS
但我需要受影响的身份证

对不起,问题很简单

更新

有了@dmitry senkovich,我可以用rawSQL来完成,但不能用hibernate。这里有一个单独的问题

https://stackoverflow.com/questions/44641851/java-hibernate-org-hibernate-exception-sqlgrammarexception-could-not-extract-re
如果updateTime是datetime 您可以使用select选择所有受影响的记录ID

日期更新时间=新日期;//更新时间


下面的解决方案怎么样

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;

更新表中的大量行是一项缓慢的操作。这是因为在由于显式回滚、更新失败、同一事务中的失败或后续查询或更新完成前的电源故障而回滚时,需要捕获每行的“旧”值

通常的解决办法是重新考虑需要进行大规模更新的应用程序设计

另一方面,该模式可能存在修复。请提供SHOW CREATE TABLE,这样我就不必在下面的段落中做太多的“挥手”了

最好将需要更新的列移动到单独的、并行的、表垂直分区中。这可能是有益的,如果

原始表有很多宽列文本、BLOB等,不需要大量复制。 原始表正在同时更新-更新不会相互阻塞。 通过避免某些其他阻塞,可以选择命中未更新的列。
您仍然可以通过将两个表连接在一起来获取原始列集。

我需要获取ID,然后更新这些ID。我只需要使用1个sql语句或使其尽可能快…@chiperortiz-尽可能快-在您证明这是代码中最慢的部分之前,不要担心优化此语句。如果您希望最小化资源使用并最大限度地提高性能,您必须使用游标或使用游标的存储过程。如果您不在乎浪费一些周期,并且您的时钟是可靠的,那么您还可以更改算法以首先进行更新。更新后,您可以使用为行设置的时间戳获取ID,在何处子句中,我如何使用hibernate使用sqlQuery或其他方式返回这些ID?@chiperortiz我看到的最简单的方法是使用本机查询:session.createSQLQuerythis_long_query_,但使用它我可以获取ID?我会查出来。@chiperortiz您将得到以下格式的字符串id1、id2、id3。。。。这是迄今为止我发现的唯一一个仅使用一次调用的方法。我已经尝试了此代码会话。createSQLQuerylongQuery.uniqueResult,但引发异常的原因是:java.sql.SQLException:无法使用executeQuery发出数据操作语句。