【问题标题】:For loops in java over a range of records in a databaseJava中的for循环在数据库中的一系列记录上
【发布时间】:2018-07-25 14:14:27
【问题描述】:

我有两个 id,它们对应于数据库中的一系列记录。我想分批处理 1000 条记录。假设这两个 id 是 51234 和 59265。我想循环遍历并确保处理所有记录。

我从下面的 for 循环开始

for(int i = 51234; i < 59265; i= i+1000) {

select * from database where id between i and i+1000;
//do the stuff
}

现在这可以正常工作到第 59234 条记录,那么最后 31 条记录呢?我想在这次运行中处理它们。

我可能可以检查每次迭代中 i 的值是多少,并检查向查询添加 1000 是否超过最大 id 并调整 sql 查询。这是唯一的方法吗?这里的 for 循环是正确的方法吗?

【问题讨论】:

  • 我看不出这不起作用的原因。
  • 最好在单个 SQL 语句命中从 DB 加载所有直到 59265 并使用 Brandons 回答。 DB命中可能很昂贵!

标签: java mysql loops


【解决方案1】:
   int batchSize=1000;
   for(int i = 51234; i <= 59265; i+=batchSize) {        
    select * from database where id between i and Math.min(i+batchSize, 59265);
    //do the stuff
    }

样本输出:

between 51234 and 52234 actualBatch=1000
between 52234 and 53234 actualBatch=1000
between 53234 and 54234 actualBatch=1000
between 54234 and 55234 actualBatch=1000
between 55234 and 56234 actualBatch=1000
between 56234 and 57234 actualBatch=1000
between 57234 and 58234 actualBatch=1000
between 58234 and 59234 actualBatch=1000
between 59234 and 59265 actualBatch=31

由于 between 包含在内,因此每个批次都有重叠。你可以改变它并使用不等式来解决这个问题:

 int batchSize = 1000;
 int start=51234;
 int end=59265;
 for(int i = start; i < end + 1; i+=batchSize) {
   select * from database where id >= i and id < Math.min(i+batchSize, end);
 } 

样本输出:

id >= 51234 and id < 52234 actualBatch=1000
id >= 52234 and id < 53234 actualBatch=1000
id >= 53234 and id < 54234 actualBatch=1000
id >= 54234 and id < 55234 actualBatch=1000
id >= 55234 and id < 56234 actualBatch=1000
id >= 56234 and id < 57234 actualBatch=1000
id >= 57234 and id < 58234 actualBatch=1000
id >= 58234 and id < 59234 actualBatch=1000
id >= 59234 and id < 59266 actualBatch=32

【讨论】:

  • 我当然会用一些变量来清理它的起始值、结束值和块大小
  • 这行得通,但最后一次迭代会一直持续下去,因为 i 的值永远不会超过 59265。我将不得不添加一个条件 i= 59265 并跳出循环。
  • @arjunj 很好。实际上,您需要做的就是删除您递增 i 部分的 Math.min。我已经在上面更正了。
  • 是的,我确实最终更改了查询以处理这种情况。谢谢!
【解决方案2】:

你可以使用do-while循环:

int i = 51234;
do {
  // call DB: select * from database where id between i and i+1000
  // do stuff
  i = i + 1000;
} while (i < 59265);

【讨论】:

    【解决方案3】:

    一个简单的解决方案是中断 for 循环并分别执行剩余的 id。

    int i = 0;
    for(i = 51234; i < 59265; i= i+1000) {
        doAllStuff(i, 1000);
        if(59265-i < 1000)
            break;
    }
    doAllStuff(i, 59265-i);
    

    doAllStuff() 如下所示:

    public void doAllStuff(int x, int y) {
        select * from database where id between x and y;
        //do the stuff
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-12-07
      • 1970-01-01
      • 2012-12-30
      • 2019-10-18
      • 2011-12-08
      • 2020-04-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多