如何使用Oracle JDBC驱动程序一次获取所有行

时间:2018-04-27 12:07:33

标签: java oracle jdbc prepared-statement resultset

我有一个返回~6,000行的查询。我需要返回所有行,以便它们可以用于生成执行批处理作业的R脚本。我执行查询并迭代填充ArrayList的ResultSet的方法花了3秒钟(客户抱怨的速度太慢)。我通过运行初始查询得到行数,然后将PreparedStatement的Fetch Size设置为此计数,将其降低到0.7秒。

旧(精简)代码:

public List<MyClass> loadFromDb() {
    try {
        String sql = "SELECT a, b FROM table1, table2, LEFT JOIN table3...";
        ResultSet result = connection.prepareStatement(sql).executeQuery();
        List<MyClass> values = new ArrayList<>();
        while (result.hasNext()) {
            values.add(new MyClass(result.getString(1), result.getString(2)));
        }
        result.close();
        return values;
    } catch (SQLException e) {
        e.printStackTrace();
        return Collections.emptyList();
    }
}

新代码:(注意我们现在可以将ArrayList初始化为所需的确切大小)

public List<MyClass> loadFromDb() {
    try {
        String sqlWithoutSelectClause = " FROM table1, table2, LEFT JOIN table3...";
        int rowCount = getCount(sqlWithoutSelectClause);
        String sql = "SELECT a, b" + sqlWithoutSelectClause;
        PreparedStatement statement = connection.prepareStatement(sql);
        statement.setFetchSize(rowCount);
        ResultSet result = statement.executeQuery();
        List<MyClass> values = new ArrayList<>(rowCount);
        while (result.hasNext()) {
            values.add(new MyClass(result.getString(1), result.getString(2)));
        }
        result.close();
        return values;
    } catch (SQLException e) {
        e.printStackTrace();
        return Collections.emptyList();
    }
}

private int getCount(String sqlWithoutSelectClause) {
    String sql = "SELECT COUNT(1) " + sqlWithoutSelectClause;
    try {
        ResultSet result = connection.prepareStatement(sql).executeQuery();
        result.next();
        int count = result.getInt(1);
        result.close();
        return count;
    } catch (SQLException e) {
        e.printStackTrace();
        return 0;
    }
}

我只使用JDBC,而不是Hibernate。我正在连接到Oracle数据库。

我的问题是,是否有一种更有效的方法可以一次获取所有行,而不是执行额外的查询来获取行数。我找不到将获取大小设置为“所有行”的方法。

0 个答案:

没有答案