Java MySQL每行循环(大表)

Java MySQL每行循环(大表),java,mysql,Java,Mysql,我有一个带有ID和name的表。我想检查一下这张桌子的每一行。 ID是一个主键和自动增量 我不能使用(?)单个查询来获取所有行,因为表太大了。 我正在做一些事情,每一个结果。我希望有可能停止这项任务,以后再继续 我想我可以这样做: for (int i = 0; i < 90238529; i++) { System.out.println("Current ID :" + i); query = "SELECT name FROM table_name WHERE id = "

我有一个带有
ID
name
的表。我想检查一下这张桌子的每一行。
ID
是一个
主键
自动增量

我不能使用(?)单个查询来获取所有行,因为表太大了。 我正在做一些事情,每一个结果。我希望有可能停止这项任务,以后再继续

我想我可以这样做:

for (int i = 0; i < 90238529; i++) {
  System.out.println("Current ID :" + i);
  query = "SELECT name FROM table_name WHERE id = " + i;
  ...
}
for(int i=0;i<90238529;i++){
System.out.println(“当前ID:+i”);
query=“从表中选择名称,其中id=“+i;
...
}
但这不起作用,因为
自动增量
跳过了一些数字


如前所述,我需要一个选项来停止这项任务,使我能够从离开的地方重新开始。与上面的示例代码一样,我知道当前条目的
ID
,如果我想再次启动它,我只需设置
int I=X

,使用单个查询获取所有记录:

query = "SELECT name FROM table_name WHERE id > ? ORDER BY id";
然后迭代
ResultSet
并读取所需的记录数(不必读取ResultSet返回的所有行)


下次运行查询时,请传递上次执行时获得的最后一个ID。

您提到这是一个大表。重要的是要注意

结果集

默认情况下,结果集被完全检索并存储在内存中。在大多数情况下,这是最有效的操作方式,并且由于MySQL网络协议的设计更易于实现。如果您使用的结果集具有大量行或大值,并且无法在JVM中为所需内存分配堆空间,则可以告诉驱动程序一次将结果流回到一行

要启用此功能,请按以下方式创建语句实例:

stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,
              java.sql.ResultSet.CONCUR_READ_ONLY);
stmt.setFetchSize(Integer.MIN_VALUE);
所以,我认为你需要这样做,我会使用。接下来,我建议您让数据库帮助您迭代行

String query = "SELECT id, name FROM table_name ORDER BY id";
try (PreparedStatement ps = conn.prepareStatement(query,
        ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
        ResultSet rs = ps.executeQuery();) {
    while (rs.next()) {
        int id = rs.getInt("id");
        String name = rs.getString("name");
        System.out.printf("id=%d, name=%s%n", id, name);
    }
} catch (SQLException e) {
    e.printStackTrace();
}
我不能使用单个查询来获取所有行,因为表太大了,我正在对每个结果进行处理。此外,我希望有可能停止这项任务,并继续它以后

这两个原因都不能消除使用单个查询的问题。它只会影响性能(使一个连接长时间处于活动状态,而不是不断打开和关闭连接,这可以通过使用连接池来缓解)

如前所述,我需要一个选项来停止这项任务,但这样我就可以从我离开的地方重新开始。就像上面的示例代码一样,我知道当前条目的ID,如果我想再次启动它,我只需设置int I=X

如果你仔细想想,就像你自己说的那样,这也行不通

但这不起作用,因为自动增量跳过了一些数字

更重要的是,自上次查询数据库以来,行可能已被插入或删除

首先,这听起来像是一个经典的XY问题(你用你的问题解决方案来描述一个问题,而不是实际的问题)。第二,似乎正在使用RDBM来处理它从未真正设计过的东西(队列)

如果您真的想这样做,而不是使用更适合的数据库,那么有许多方法可以使用。第一个问题是,您希望从某个点/状态恢复,但该点/状态未存储在数据库中,因此在存在多个DB连接的情况下不起作用。解决此问题的第一种方法是在表中引入一个“已处理”字段(如果要从任意点恢复,可以使用UPDATE语句清除该字段),现在取决于实际要解决的问题,它可以是一个简单的真/假字段,是当前处理线程的唯一标识符,或者一个关系表。取决于需求


然后,您可以继续使用SQL来获取所需的数据。

显然,表还没有那么大。但是谢谢,这可能会在以后有用。你真是天才!非常感谢。