【问题标题】:spring batch: efficient way to query results of a stored procedure within a taskletspring batch:查询小任务中存储过程结果的有效方法
【发布时间】:2020-03-04 15:42:58
【问题描述】:

我的目标是使用 spring 批处理 tasklet 中的自定义行映射器查询存储过程 (sql server) 的结果。

我正在使用 Spring Boot(版本 2.2.2.RELEASE)和 Spring Batch(4.2.1.RELEASE)。

例子:

存储过程:

CREATE PROCEDURE storedProcName @numbers VARCHAR(max), @day DATE
AS
SET NOCOUNT ON;

SELECT something, something2, something3
FROM sometable
WHERE ids in (select value from string_split(@numbers,','))
AND day = @day

自定义行映射器:

public class CustomRowMapper implements RowMapper<CustomObject> {
    private static final String SOMETHING = "something";
    private static final String SOMETHING2 = "something2";
    private static final String SOMETHING3 = "something3";

    @Override
    public CustomObject mapRow(ResultSet resultSet, int i) throws SQLException {
        CustomObject customObject = new CustomObject();
        customObject.setSomething(resultSet.getString(SOMETHING));
        customObject.setSomething2(resultSet.getString(SOMETHING2));
        customObject.setSomething3(resultSet.getInt(SOMETHING3));

        return customObject;
    }
}

执行存储过程并查询结果:

SimpleJdbcCall jdbcCall = new SimpleJdbcCall(jdbcTemplate)
        .withProcedureName("storedProcName")
        .returningResultSet("test", new CustomRowMapper());
Map<String, Object> out = jdbcCall.execute(parameterSource);
List<CustomObject> customObjects = (List<CustomObject>) out.get("test");

它工作正常,但必须有更有效的方法来做到这一点?但我没有发现任何有用的东西。

【问题讨论】:

    标签: sql-server spring stored-procedures spring-batch spring-jdbc


    【解决方案1】:

    必须有更有效的方法来做到这一点

    Spring Batch 提供了StoredProcedureItemReader,它可以调用给定的存储过程并迭代其结果。它还允许您使用自定义映射器作为您定义的映射器。

    根据您的代码 sn-p,您调用该过程并获得一个 List&lt;CustomObject&gt;,您需要在某个时候对其进行迭代。所以我认为带有StoredProcedureItemReader&lt;CustomObject&gt; 的面向块的tasklet 对你来说是个不错的选择:

    @Bean
    public StoredProcedureItemReader<CustomObject> itemReader() {
        return new StoredProcedureItemReaderBuilder<CustomObject>()
                .procedureName("storedProcName")
                .rowMapper(new CustomRowMapper())
                // set other properties
                .build();
    }
    

    编辑:展示如何返回同步阅读器

    @Bean
    @StepScope
    public SynchronizedItemStreamReader<CustomObject> itemReader() {
        StoredProcedureItemReader<CustomObject> reader = new StoredProcedureItemReaderBuilder<>()
                .procedureName("storedProcName")
                .rowMapper(new CustomRowMapper())
                // set other properties
                .build();
    
        SynchronizedItemStreamReader<CustomObject> synchronizedReader = new SynchronizedItemStreamReader<>();
        synchronizedReader.setDelegate(reader);
        return synchronizedReader;
    }
    

    【讨论】:

    • 我读到 StoredProcedureItemReader 不是线程安全的,因为它基于 ResultSet。如何将其包装到 SynchronizedItemStreamReader 中以使其线程安全?
    • 谢谢。那行得通。但我也必须添加@StepScope。
    猜你喜欢
    • 2012-08-01
    • 2010-10-10
    • 1970-01-01
    • 2018-12-27
    • 2013-05-19
    • 1970-01-01
    • 1970-01-01
    • 2010-09-09
    • 1970-01-01
    相关资源
    最近更新 更多