6

有什么方法可以从 jdbctemplate 查询方法之一获取结果集对象?

我有一个类似的代码

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

我想执行存储在 finalQuery 字符串中的 sql 语句并获取结果集。该查询是对 6 到 7 个表的复杂连接,我从每个表中选择 4-5 列,并希望获取这些列的元数据以将数据类型和数据转换到下游系统。

如果它是一个简单的查询并且我只从一个表中获取我可以使用 RowMapper#mapRow 并且在该 maprow 方法中我可以调用 ResultsetExtractor.extractData 来获取结果列表;但在这种情况下,我的查询中有复杂的连接,我试图从结果集元数据中获取结果集对象......

上面的代码不好,因为对于每个结果,它都会返回相同的结果集对象,我不想将它们存储在列表中......

还有一点是,如果我的查询中的每个结果都调用了 maprow,那么即使我的列表引用了 RS 对象,JDBCTemplate 也会关闭 rs 和连接吗?

有没有像 jdbcTemplate.queryForResultSet(sql) 这样的简单方法?

现在我已经实现了自己的 ResultSet Extractor 来处理数据并将其插入下游系统

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

这个 CustomResultSetProcessor 实现了 ResultSetExtractor 并且在 extractData 方法中我调用了 3 种不同的方法 1 是从 rs.getMetaData() 中获取 ColumnTypes ,其次是通过运行获取目标元数据的列类型

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{} }

希望这对其他人有帮助...

4

3 回答 3

6

请注意,Spring JDBC 模板的全部意义在于它ResultSet在执行回调方法后自动关闭所有资源,包括 . 因此,最好在回调方法中提取必要的数据并允许 Spring 关闭ResultSet它之后。

如果数据提取的结果不是 a 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
        }
    });
于 2011-03-15T15:46:25.203 回答
3

像这样的东西也可以工作:

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

ResultSet rs = s.executeQuery(query); // your query
ResultSetMetaData rsmd = rs.getMetaData();
于 2012-09-28T15:51:56.463 回答
2

尽管我同意#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);
    }
}
于 2016-07-05T15:54:38.893 回答