Итерируемый результат от Spring JdbcTemplate - PullRequest
0 голосов
/ 23 января 2019

Spring JdbcTemplate удобно возвращает результаты запроса в виде одного значения, одной строки и коллекции. Мое приложение обрабатывает результат последовательно и только один раз, поэтому я не хочу загружать память ненужным накоплением. Нужно что-то вроде Iterator. Пробовал это:

    try (ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("jdbc-context.xml")) {
        DataSource dataSource = (DataSource) ctx.getBean("dataSource");

        JdbcTemplate jоdbcTemplate = new JdbcTemplate(dataSource);

        SqlRowSet rs = jоdbcTemplate.queryForRowSet("select rownum from dual connect by rownum <= ?", 15);

        while(rs.next()) {
            System.out.println(rs.getInt(1));
        }
    }

Но, похоже, SqlRowSet является отключенной версией стандарта Java ResultSet , и в реализации результат запроса по-прежнему накапливается первым.

Как получить итеративный однопроходный результат запроса из JdbcTemplate без накопления?

РЕШЕНИЕ

Как это было предложено @ GPI

    try (ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("jdbc-context.xml")) {
        DataSource dataSource = (DataSource) ctx.getBean("dataSource");

        JdbcTemplate jоdbcTemplate = new JdbcTemplate(dataSource);

        ResultSetExtractor<Boolean> rse = new ResultSetExtractor<Boolean>() {

            @Override
            public Boolean extractData(ResultSet rs) throws SQLException, DataAccessException {

                while(rs.next()) {
                    System.out.println(rs.getInt(1));
                }
                return null;
            }
        };

        jоdbcTemplate.query("select rownum from dual connect by rownum <= ?", new Integer[] {15}, rse);
    }

По крайней мере, это работает. Кажется, больше нет естественных решений. Возможно, вернемся к стандартному JDBC и ResultSet.

1 Ответ

0 голосов
/ 23 января 2019

Если вы не хотите накапливать что-либо на «стороне пружины» кода, тогда вам проще всего набрать query, используя ResultSetExtractor

ResultSetExtractor поставляется с JDBC ResultSet, с которым вы можете выполнять итерации.

Насколько я знаю, нет способа иметь Iterable и каким-либо образом не кэшировать содержимое SQL (итерируемыеможет воссоздать столько итераторов, сколько хочет вызывающий, что означает, что он должен иметь возможность «запоминать» все).

При этом сам драйвер SQL может или не может сам кэшировать данные, чтодругое обсуждение, которое не относится к Spring.

Вы должны прочитать документацию к своему драйверу SQL, чтобы найти возможные варианты оптимизации (размеры выборки, прямая прокрутка, ...) и, если необходимо, использовать SpringPreparedStatementCreator для изменения параметров JDBC, которые Spring использует для построения запроса.

...