将数据从分区程序传递到JdbcCursorItemReader

时间:2015-03-23 09:35:50

标签: spring spring-batch

我正在尝试使用sping batch Partitioner进行块处理步骤。我想使用stepexecutioncontext将数据从Partitioner传递到我的itemreader步骤,但无法这样做。

以下是我的配置 -

分区 -

public class MyPartitioner implements Partitioner{
@Override
public Map<String, ExecutionContext> partition(int gridSize)
{
    Map<String, ExecutionContext> partitionMap = new HashMap<String, ExecutionContext>();
    List<String> codes = getCodes();

    for (String code : codes)
    {
        ExecutionContext context = new ExecutionContext();
        context.put("code", code);
        partitionMap.put(code, context);
    }
    return partitionMap;
}}

Job config.xml -

<bean id="MyPartitioner" class="com.MyPartitioner" />
<bean id="itemProcessor" class="com.MyProcessor" scope="step" />
<bean id="itemReader" class="org.springframework.batch.item.database.JdbcCursorItemReader" scope="step" >
  <property name="dataSource" ref="dataSource"/>
  <property name="sql" value="select * from mytable WHERE code = '#{stepExecutionContext[code]}' "/>
  <property name="rowMapper">
      <bean class="com.MyRowMapper" scope="step"/>
  </property>
</bean>
<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor" >
    <property name="corePoolSize" value="20"/>
    <property name="maxPoolSize" value="20"/>
    <property name="allowCoreThreadTimeOut" value="true"/>
</bean>

  <bean id="itemWriter" class="org.springframework.batch.item.database.JdbcBatchItemWriter" scope="step">
    <property name="dataSource" ref="dataSource"/>
    <property name="sql" value="some sql" />

    <property name="itemSqlParameterSourceProvider">
        <bean class="org.springframework.batch.item.database.BeanPropertyItemSqlParameterSourceProvider"/>
    </property>
</bean>

<batch:step id="Step1" xmlns="http://www.springframework.org/schema/batch">
    <batch:tasklet transaction-manager="transactionManager">
        <batch:chunk reader="itemReader"  processor="itemProcessor" writer="itemWriter" commit-interval="200"/>
    </batch:tasklet>
</batch:step>
<batch:job id="myjob">
    <batch:step id="mystep">
        <batch:partition step="Step1" partitioner="MyPartitioner">
            <batch:handler grid-size="20" task-executor="taskExecutor"/>
        </batch:partition>
    </batch:step>
</batch:job> 

此代码在作为独立应用程序运行时工作正常,但在服务器应用程序内运行时,itemreader步骤将查询读取为

从mytable WHERE code ='#{stepExecutionContext [code]}'中选择*而不是

从mytable WHERE code ='mycode'中选择*。

请告诉我我做错了什么,或者是否需要为服务器应用程序内的其他配置工作?

由于

1 个答案:

答案 0 :(得分:1)

您可以设置自己的扩展JdbcCursorItemReader的类,使其成为@StepScope并添加@BeforeStep

@BeforeStep
public void beforeStep(final StepExecution stepExecution) {
    final String code = execution.getExecutionContext().getString("code");
    final String sql = buildSql(code); //method which creates sql statement
}

在其中你有StepExecution并且你可以获取你需要的变量来构建你的sql。覆盖afterPropertiesSet()以设置sqlrowMapperdataSource

@Override
public void afterPropertiesSet() throws Exception {
    setSql(sql);
    setRowMapper(rowMapper);
    setDataSource(dataSource);
    super.afterPropertiesSet();
}

使用java代码而不是xml应始终是IMO首选方法,因为您手头有代码,您可以调试,这样可以避免潜在的xml输入错误。这种方法也是可以测试的。