使用自定义 ItemReader 调用带有 IN 和 OUT 参数的存储过程

Calling a stored procedure with IN and OUT parameters using custom ItemReader

我在 Whosebug 上问了这个关于使用 StoredProcedureItemReader 调用带有 IN 和 OUT 参数的存储过程的问题,但不幸的是,答案是这种支持不可用,我必须实现自己的 ItemReader .

所以,我继续写了这个示例代码。我可以调用我的存储过程,但是,只要在批处理步骤中调用 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;
    }
}

我做错了什么,正确的做法是什么?

I am able to call my stored procedure, however, it's being called infinite times whenever the read() method is called in a Batch step.

ItemReader 预计在某个时间点 return null 表示数据集结束。这就是驱动的面向块的步骤如何知道没有更多数据要读取并将控制权交给封闭作业以移动到下一步(如果有的话)。

所以在你的情况下,你需要确保你的项目 reader returns null 在某个时候。