Метаданные Resultset из методов Spring JDBCTemplate Query - PullRequest
5 голосов
/ 15 марта 2011

Есть ли способ получить объект набора результатов из одного из методов запроса jdbctemplate?

У меня есть код вроде

List<ResultSet> rsList = template.query(finalQuery, new RowMapper<ResultSet>() {
        public ResultSet mapRow(ResultSet rs, int rowNum) throws SQLException {
            return rs;
        }
        }
        );

Я хотел выполнить инструкцию sql, хранящуюся в finalQuery String, и получить набор результатов. Запрос представляет собой сложное объединение для 6-7 таблиц, и я выбрал 4-5 столбцов в каждой таблице и хотел получить метаданные этих столбцов для преобразования типов данных и данных в последующие системы.

Если это простой запрос, и я выбираю только одну таблицу, я могу использовать RowMapper # mapRow и внутри этого метода maprow я могу вызвать ResultsetExtractor.extractData, чтобы получить список результатов; но в этом случае у меня есть сложные объединения в моем запросе, и я пытаюсь получить объект набора результатов и из метаданных этого набора результатов ...

Приведенный выше код не годится, поскольку для каждого результата он возвращает один и тот же объект набора результатов, и я не хочу хранить их в списке ...

Еще раз: если для каждого результата из моего запроса вызывается maprow, JDBCTemplate закроет rs и соединение, даже если в моем списке есть ссылка на объект RS?

Есть ли какой-нибудь простой метод, такой как jdbcTemplate.queryForResultSet (sql)?

Теперь я реализовал свой собственный ResultSet Extractor для обработки и вставки данных в последующие системы

sourceJdbcTemplate.query(finalQuery, new CustomResultSetProcessor(targetTable, targetJdbcTemplate));

Этот CustomResultSetProcessor реализует ResultSetExtractor, и в методе extractData я вызываю 3 различных метода: 1 - получить форму ColumnTypes rs.getMetaData (), а вторым - getColumnTypes целевых метаданных, выполнив

SELECT NAME, COLTYPE, TBNAME FROM SYSIBM.SYSCOLUMNS WHERE TBNAME ='TABLENAME' AND TABCREATOR='TABLE CREATOR'

и в третьем методе я создаю оператор вставки (подготовленный) из целевого типа столбца и, наконец, вызываю его, используя

new BatchPreparedStatementSetter()
    {
        @Override
        public void setValues(PreparedStatement insertStmt, int i) throws SQLException{} }

Надеюсь, это поможет другим ...

Ответы [ 3 ]

3 голосов
/ 15 марта 2011

Обратите внимание, что весь смысл Spring JDBC Template заключается в том, что он автоматически закрывает все ресурсы, включая ResultSet, после выполнения метода обратного вызова.Поэтому было бы лучше извлечь необходимые данные внутри метода обратного вызова и позволить Spring закрыть ResultSet после него.

Если результатом извлечения данных не является List, вы можете использовать ResultSetExtractor вместоиз RowMapper:

SomeComplexResult r = template.query(finalQuery, 
    new ResultSetExtractor<SomeComplexResult>() {
        public SomeResult extractData(ResultSet) {
            // do complex processing of ResultSet and return its result as SomeComplexResult
        }
    });
2 голосов
/ 28 сентября 2012

Примерно так же будет работать:

Connection con = DataSourceUtils.getConnection(dataSource); // your datasource
Statement s = con.createStatement();

ResultSet rs = s.executeQuery(query); // your query
ResultSetMetaData rsmd = rs.getMetaData();
1 голос
/ 05 июля 2016

Хотя я согласен с #axtavt, что ResultSetExtractor является предпочтительным в среде Spring, он действительно заставляет вас выполнить запрос.

Приведенный ниже код не требует от вас этого, поэтому код клиента не требуется для предоставления фактических аргументов для параметров запроса:

public SomeResult getMetadata(String querySql) throws SQLException {
    Assert.hasText(querySql);

    DataSource ds = jdbcTemplate.getDataSource();
    Connection con = null;
    PreparedStatement ps = null;
    try {
        con = DataSourceUtils.getConnection(ds);
        ps = con.prepareStatement(querySql);
        ResultSetMetaData md = ps.getMetaData();   //<-- the query is compiled, but not executed
        return processMetadata(md);
    } finally {
        JdbcUtils.closeStatement(ps);
        DataSourceUtils.releaseConnection(con, ds);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...