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

Posted

技术标签:

【中文标题】使用自定义 ItemReader 调用带有 IN 和 OUT 参数的存储过程【英文标题】:Calling a stored procedure with IN and OUT parameters using custom ItemReader 【发布时间】:2020-06-04 18:36:30 【问题描述】:

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

Calling stored procedure with an IN and OUT Parameter from Spring 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;
    

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

【问题讨论】:

【参考方案1】:

我可以调用我的存储过程,但是,只要在批处理步骤中调用 read() 方法,它就会被无限次调用。

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

因此,在您的情况下,您需要确保您的项目阅读器在某个时候返回 null

【讨论】:

以上是关于使用自定义 ItemReader 调用带有 IN 和 OUT 参数的存储过程的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Spring Batch 中使用 Resource ItemReader

Spring Batch ItemReader 使用 PostgreSQL 函数游标错误

如何使用自定义 IN 参数在 IBM Worklight SQL 适配器中调用存储过程

Alamofire - 带有自定义标头的 Rest API 调用

带有自定义标头的跨域 jquery ajax api 调用未命中服务器

带有 .ui 文件的 QT5 自定义小部件 - 显示时需要调用 Ui::myWidget.setupUi