15

我正在执行查询以检索大量 ID(整数)。与其通过 ResultSet 迭代数百万次并将所有内容一个接一个地复制到 ArrayList 中,有什么方法可以简单地将所有内容作为 ArrayList 检索吗?

我知道 ResultSet 应该被迭代,因为底层实现可能是缓存的东西,但在我的情况下,我只需要所有的 ID。我知道我可以将 FetchSize 设置为一个很大的数字,但是我仍然必须一个接一个地检索 ID。

澄清:我想这样做的原因是性能。分析向我展示了数百万次执行 ResultSet.next()、ResultSet.getInt() 和 ArrayList.add() 需要相当长的时间。我认为数据库(我使用的是用 Java 编写的 H2)可能在内存中的某处有数组或列表,所以我正在寻找一种方法将其直接复制给我,而不是通过 ResultSet 迭代接口.

4

3 回答 3

17

使用 Apache DbUtils库,您可以轻松地将 ResultSet 作为地图列表返回。

public List query(String query) {
    List result = null;
    try {
        QueryRunner qrun = new QueryRunner();
        result = (List) qrun.query(connection, query, new MapListHandler());
    } catch (Exception ex) {
        ex.printStackTrace();
    }
    return result;
}
于 2009-03-13T11:38:51.343 回答
6

将代码放入方法中。调用方法很简单...

在我的头顶上:

public static List<Integer> readInts(
     PreparedStatement statement
) throws SQLException {
     ResultSet results = statement.executeQuery();
     try {
         assert results.getMetaData().getColumnCount() == 1;

         List<Integer> ints = new ArrayList<Integer>();
         while (results.next()) {
             ints.add(Integer.valueOf(results.getInt(1)));
         }
         return ints;
     } finally {
         results.close();
     }
}

然后将其称为:

List<Integer> ids = readInts(myStatemnet);

完毕。

于 2009-03-13T11:38:16.167 回答
5

如果您的问题是性能不佳,请在执行之前调整语句

java.sql.Statement.setFetchSize(int)

尝试 100、1000、10000,.. 这将避免不必要的往返,这可能是您提到的缓慢的原因。

此外,如果必须多次调整内部数组的大小,ArrayList.add() 可能会很慢,因为它会创建一个新数组并将所有数据复制到那里。改用 LinkedList。

于 2009-03-13T16:16:46.013 回答