Как управлять большим набором данных с помощью MySQL Spring и RowCallbackHandler

Я пытаюсь пробежаться через каждую строку таблицы в 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, потому что он пытается считать все это. Какие-либо идеи?

7
задан Ricardo Marimon 19 January 2010 в 17:25
поделиться

3 ответа

Заявление # 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 с помощью пользовательской реализации. Как я не делаю весну, я не могу подробно посмотреть об этом, но теперь вы хотя бы знаете, где смотреть.

Удачи.

9
ответ дан 6 December 2019 в 06:36
поделиться

Если вы подозреваете, что вы получаете ошибку OutoFMemory из-за всей таблицы, почему вы не пытаетесь разделить ваш запрос. Используйте фильтры, предельную оговорку и т. Д.

0
ответ дан 6 December 2019 в 06:36
поделиться

Вот решение 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);
18
ответ дан 6 December 2019 в 06:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: