Java 如何使用Spring MySQL和RowCallbackHandler管理大型数据集
我试图使用Spring和JdbcTemplate检查MySQL中表的每一行。如果我没弄错的话,这应该简单到: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
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的答案更合适。多谢。