我在Stackoverflow上问了这个问题,关于使用StoredProcedureItemReader调用带有IN和OUT参数的StoredProcedure,但不幸的是,答案是没有这样的支持,我必须实现自己的ItemReader。
从Spring Batch调用带有IN和OUT参数的StoreProcedure。
所以,我继续写了这个示例代码。我能够调用我的存储过程,但是,每当在Batch步骤中调用read()方法时,它就会被无限次地调用。
@Component
public class MyStoredProcItemReader implements ItemReader<MyRow> {
@Autowired DataSource dataSource;
@Override
public MyRow read() throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {
try (
Connection conn = dataSource.getConnection();
CallableStatement statement = conn.prepareCall("{call GetNameCountByFname(?, ?)}");
) {
statement.setString(1, "bob");
statement.registerOutParameter(2, Types.INTEGER);
boolean hadResults = statement.execute();
Integer totalBook = (Integer) statement.getObject(2, Integer.class);
System.out.println("Total: " + totalBook);
Map<String, Object> results = new HashMap<>();
// ResultSet resultSet = statement.getResultSet();
// ResultSetMetaData metaData = resultSet.getMetaData();
// int col = 1;
// while (resultSet.next())
// {
// String columnName = metaData.getColumnName(col);
// Object value = resultSet.getObject(col);
// results.put(columnName, value);
// ++col;
// }
//
// int columnCount = metaData.getColumnCount();
// for (int col = 1; col <= columnCount; col++) {
// String columnName = metaData.getColumnName(col);
// Object value = resultSet.getObject(col);
//
// results.put(columnName, value);
// }
while (hadResults) {
ResultSet resultSet = statement.getResultSet();
// process result set
while (resultSet.next()) {
String title = resultSet.getString("id");
String description = resultSet.getString("name");
int rating = resultSet.getInt("LastSynchronizationVersion");
System.out.println(
"| " + title + " | " + description + " | " + rating + " |");
}
hadResults = statement.getMoreResults();
}
statement.close();
MyRow row = new MyRow();
row.tableName = "tableName";
row.row = results;
return row;
} catch (SQLException ex) {
ex.printStackTrace();
}
return null;
}
}
我做错了什么,正确的方法是什么?
我能够调用我的存储过程,但是,每当在Batch步骤中调用read()方法时,它就会被无限次调用。
一个 ItemReader
预计将返回 null
在某个点上发出数据集结束的信号。这就是面向驱动块的步骤如何知道没有更多的数据可读,并将控制权交给包围作业,使其进入下一步(如果有的话)。
所以在你的情况下,你需要确保你的项目读取器返回的是 null
在某些时候。