Spring JDBCTemplate查询方法的结果集元数据

时间:2011-03-15 15:36:51

标签: spring metadata resultset jdbctemplate

有什么办法可以从jdbctemplate查询方法中获取结果集对象吗?

我有像

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

我想执行存储在finalQuery String中的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,通过运行

获取目标元数据的ColumnTypes形式的rs.getMetaData()和第二个是getColumnTypes
SELECT NAME, COLTYPE, TBNAME FROM SYSIBM.SYSCOLUMNS WHERE TBNAME ='TABLENAME' AND TABCREATOR='TABLE CREATOR'

并且在第3种方法中,我正在构建目标columntypes的insert语句(准备好),最后使用

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

希望这有助于其他人......

3 个答案:

答案 0 :(得分:3)

请注意,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
        }
    });

答案 1 :(得分:2)

这样的事情也可行:

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

ResultSet rs = s.executeQuery(query); // your query
ResultSetMetaData rsmd = rs.getMetaData();

答案 2 :(得分:1)

虽然我同意#axtavt在Spring环境中首选ResultSetExtractor,但它会强制您执行查询。

以下代码不要求您这样做,因此客户端代码不需要提供查询参数的实际参数:

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);
    }
}