我正在尝试使用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'中选择*。
请告诉我我做错了什么,或者是否需要为服务器应用程序内的其他配置工作?
由于
答案 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()
以设置sql
,rowMapper
和dataSource
。
@Override
public void afterPropertiesSet() throws Exception {
setSql(sql);
setRowMapper(rowMapper);
setDataSource(dataSource);
super.afterPropertiesSet();
}
使用java代码而不是xml应始终是IMO首选方法,因为您手头有代码,您可以调试,这样可以避免潜在的xml输入错误。这种方法也是可以测试的。