Я пытаюсь пробежаться через каждую строку таблицы в MySQL с помощью Spring и JdbcTemplate. Если я не ошибаюсь, это должно быть столь же просто как:
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, потому что он пытается считать все это. Какие-либо идеи?
Заявление # setfetchsize ()
javadoc уже говорится:
дает драйвер JDBC A подсказку относительно количества строк Это должно быть получено из базы данных
, водитель действительно свободно применять или игнорировать намек. Некоторые водители игнорируют его, некоторые водители применяют его напрямую, некоторые драйверы нуждаются в большем количестве параметров. Драйвер MySQL JDBC попадает в последнюю категорию. Если вы проверяете водительскую документацию MySQL JDBC , вы увидите следующую информацию (прокрутите около 2/3 вниз до заголовка Resultset ):
, чтобы включить эту функциональность, вам нужно Чтобы создать экземпляр операторов следующим образом:
STMT = Conn.CreateStatement (Java.sql.resultset.type_forward_only, java.sql.resultset.concur_read_only); stmt.setfetchsize (integer.min_value);
Пожалуйста, прочитайте раздел в целом раздел документа, он также описывает предостережения этого подхода.
Чтобы заставить его работать весной, вам нужно будет расширить / переопределить JDBCTEMPLATE с помощью пользовательской реализации. Как я не делаю весну, я не могу подробно посмотреть об этом, но теперь вы хотя бы знаете, где смотреть.
Удачи.
Если вы подозреваете, что вы получаете ошибку OutoFMemory из-за всей таблицы, почему вы не пытаетесь разделить ваш запрос. Используйте фильтры, предельную оговорку и т. Д.
Вот решение Spring, основанное на ответе , предоставленном BalusC.
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);