如何使用Spring MySQL和RowCallbackHandler管理大型数据集

Ric*_*mon 7 java mysql spring jdbc

我正在尝试使用Spring和JdbcTemplate遍历MySQL中的每一行表.如果我没有弄错,这应该是这样简单:

JdbcTemplate template = new JdbcTemplate(datasource);
template.setFetchSize(1);
// template.setFetchSize(Integer.MIN_VALUE) does not work either            
template.query("SELECT * FROM cdr", new RowCallbackHandler() {
  public void processRow(ResultSet rs) throws SQLException {
    System.out.println(rs.getString("src"));
  }
});
Run Code Online (Sandbox Code Playgroud)

我得到一个OutOfMemoryError,因为它试图读取整个事情.有任何想法吗?

Edw*_*ale 18

这是基于BalusC提供的答案的Spring解决方案.

class StreamingStatementCreator implements PreparedStatementCreator {
    private final String sql;

    public StreamingStatementCreator(String sql) {
        this.sql = sql;
    }

    @Override
    public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
        final PreparedStatement statement = connection.prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
        statement.setFetchSize(Integer.MIN_VALUE);
        return statement;
    }
}
Run Code Online (Sandbox Code Playgroud)

代码中的某个地方:

DataSource dataSource = ...;
RowCallbackHandler rowHandler = ...;
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
jdbcTemplate.query(new StreamingStatementCreator("SELECT * FROM huge_table"), rowHandler);
Run Code Online (Sandbox Code Playgroud)


Bal*_*usC 9

Statement#setFetchSize() javadoc中已经指出:

为JDBC驱动程序提供有关应从数据库中提取的行数的提示

驱动程序实际上可以自由应用或忽略提示.一些驱动程序忽略它,一些驱动程序直接应用它,一些驱动程序需要更多参数 MySQL JDBC驱动程序属于最后一类.如果检查MySQL JDBC驱动程序文档,您将看到以下信息(向下滚动约2/3直到标题ResultSet):

要启用此功能,您需要以下列方式创建Statement实例:

stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY);
stmt.setFetchSize(Integer.MIN_VALUE);
Run Code Online (Sandbox Code Playgroud)

请阅读文档的整个部分,它也描述了这种方法的注意事项.

要使它在Spring中工作,您需要使用自定义实现扩展/覆盖JdbcTemplate.由于我不做春天,我不能详细说明这一点,但现在你至少知道在哪里看.

祝好运.

  • 我在这里添加了一个基于Spring的解决方案:http://stackoverflow.com/questions/2095490/how-to-manage-a-large-dataset-using-spring-mysql-and-rowcallbackhandler/2834590#2834590 (2认同)