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发出数据操作语句。