Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用Spring MySQL和RowCallbackHandler管理大型数据集_Java_Mysql_Spring_Jdbc - Fatal编程技术网

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

Java 如何使用Spring MySQL和RowCallbackHandler管理大型数据集,java,mysql,spring,jdbc,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", ne

我试图使用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"));
  }
});

我得到一个OutOfMemoryError,因为它试图读取整个内容。有什么想法吗?

如果您怀疑由于读取整个表而导致OutOfMemory错误,为什么不尝试拆分查询呢。使用筛选器、限制子句等。

语句#setFetchSize()已经声明:

给JDBC驱动程序一个提示,告诉它应该从数据库中获取的行数

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

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

stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY);
stmt.setFetchSize(Integer.MIN_VALUE);
请阅读本文档的整个部分,其中还介绍了这种方法的注意事项

但是,为了让它在Spring中工作,您需要使用自定义实现扩展/覆盖JdbcTemplate。因为我不做Spring,所以我不能详细说明这一点,但现在你至少知道该去哪里找了


祝你好运。

这里有一个基于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;
    }
}
在代码中的某个地方:

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

这将导致该过程的逻辑更加复杂。我现在正在测试一种通过SpringJDBCTeamplate进行流媒体传输的方法。我在这里添加了一个基于Spring的解决方案:值得注意的是,您需要确保连接字符串中的useServerPrepStmts属性设置正确,也就是说,如果这个设置为false^^不起作用,它将缓存完整的结果集,那么值得注意的是,对于Spring 3,JdbcTemplate的setFetchSize忽略小于1的限制,因此您必须覆盖一个非常基本的功能。糟糕。@AndrewGilmartin在4.3之后应该可以工作-注意:从4.3开始,除了-1以外的负值将传递给驱动程序,因为例如MySQL支持Integer.MIN_VALUE的特殊行为。嘿,请注意更改接受的答案。你的问题是关于spring的,@scompt.com的答案更合适。多谢。