Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java批处理中更新数百万行的最佳方法_Java_Mysql_Spring_Hibernate - Fatal编程技术网

在Java批处理中更新数百万行的最佳方法

在Java批处理中更新数百万行的最佳方法,java,mysql,spring,hibernate,Java,Mysql,Spring,Hibernate,我在遗留项目中使用justemain方法开发了一个批处理:使用mysql数据库的java7、hibernate和Spring 在这个批处理中,我想更新表中超过5000万行的几行。 当我每天开始批处理时,我必须更新至少10000行 那么,在mysql中更新行而不锁定表的最佳方法是什么 只需执行如下查询: update table items set is_achive = true where id in (id1,id2,id3....id10000) for(item p : ItemsLi

我在遗留项目中使用justemain方法开发了一个批处理:使用mysql数据库的java7、hibernate和Spring

在这个批处理中,我想更新表中超过5000万行的几行。 当我每天开始批处理时,我必须更新至少10000行

那么,在mysql中更新行而不锁定表的最佳方法是什么

只需执行如下查询:

update table items set is_achive = true where id in (id1,id2,id3....id10000)
for(item p : ItemsList){
   update table item  set is_achive = true where id = p.id
} 
或者使用如下的for循环:

update table items set is_achive = true where id in (id1,id2,id3....id10000)
for(item p : ItemsList){
   update table item  set is_achive = true where id = p.id
} 

使用Hibernate标准生成器:

    CriteriaBuilder cb = this.em.getCriteriaBuilder();

    // create update
    CriteriaUpdate<Order> update = cb.createCriteriaUpdate(Order.class);

    // set the root class
    Root e = update.from(Order.class);

    // set update and where clause
    update.set("amount", newAmount);
    update.where(cb.greaterThanOrEqualTo(e.get("amount"), oldAmount));

    // perform update
    this.em.createQuery(update).executeUpdate();
CriteriaBuilder cb=this.em.getCriteriaBuilder();
//创建更新
CriteriaUpdate=cb.createCriteriaUpdate(Order.class);
//设置根类
Root e=update.from(Order.class);
//set update和where子句
update.set(“金额”,newAmount);
更新。其中(cb.greaterThanOrEqualTo(e.get(“金额”),oldAmount));
//执行更新
this.em.createQuery(update.executeUpdate();

这取决于您如何确定需要更新的行列表。如果查询数据库以确定列表,最好只使用DML语句,如:

UPDATE Item i SET i.achive = true WHERE ...
如果您关心的是锁定,即锁定行的时间量,则可以通过使用游标(例如数据源的某个id)来使用批处理

SELECT id FROM ... WHERE id >= :start AND ...
ORDER BY id
OFFSET 100 -- use a batch size that suites your needs
LIMIT 1 -- use a batch size that suites your needs
可以使用查询来实现更新的限制和限制

Integer end = entityManager.createQuery("SELECT id FROM ... WHERE id >= :start AND ... ORDER BY id")
    .setParameter("start", previousEnd)
    .setFirstResult(100) // batch size
    .setMaxResults(1)
    .getResultList().stream().findFirst().orElse(null);
然后执行这样的查询

UPDATE Item i SET i.achive = true WHERE i.id BETWEEN :start AND :end
或者如果结束为空,即最后一批使用

UPDATE Item i SET i.achive = true WHERE i.id >= :start

<> P>最好是尝试去根,如果它像克里斯B建议,但如果它是你不能做的事情,那么你也可以考虑利用Spring JDBC批量更新操作,如这里所记录的。这些文档已经存在了一段时间,所以请查找适合您所使用版本的文档


Hibernate将为您批量更新,但您可能会遇到其他问题(例如内存使用),最好先尝试更容易编写的方法,并在发现问题时解决问题如果更新必须是原子的,不要忘记启动事务。否则,如果运行过程中出现异常或错误,最终可能会出现部分更新。