有什么办法可以从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()和第二个是getColumnTypesSELECT 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{} }
希望这有助于其他人......
答案 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);
}
}