我有一个弹簧批量数据库项目阅读器,如下所示:
<beans:bean id="MyItemReader" class="org.springframework.batch.item.database.JdbcCursorItemReader" scope="step">
<beans:property name="dataSource" ref="MyDataSource" />
<beans:property name="sql" value="SELECT MY_DATE, COL1, COL2 FROM MYSCHEMA.MYTABLE WHERE MY_DATE = ?" />
<beans:property name="rowMapper">
<beans:bean name="mapper" class="com.mypackage.MyRowMapper" />
</beans:property>
</beans:bean>
很明显,读者需要一个参数,我可以使用preparedStatementSetter提供该参数。
然而,问题是,我有一个参数列表,即十个日期。
我希望将所有十个日期的读者一个接一个地运行10次,然后只运行一次编写器以写入所有日期的所有读取数据。
我不能在QUERY的条件下改变,包括&#34; IN&#34;条款。我的要求是一个接一个地传递日期。
我可以使用促销听众以任何形式向读者提供10个日期。对于例如包含键值对的10个日期的地图或10个日期的列表等。
我怎样才能做到这一点?
如果有人可以指出我的自定义数据库项目阅读器示例,那就太棒了。
感谢阅读!
答案 0 :(得分:2)
您不能将MultiResourceItemReader
与自定义PreparedStatementSetter
配对的策略与您的参数进行后期绑定,因为“MyItemReader”会针对步骤进行一次评估。
我的建议是创建一个自定义ItemReader
保留List<Date>
并循环浏览此列表,直到它用完为止;阅读是使用委托和?替换是手动完成的。
public class DateListPreparedStatementSetter implements PreparedStatementSetter {
private Date date;
public void setDate(Date date) {
this.date = date;
}
public void setValues(PreparedStatement ps) throws SQLException {
ps.setDate(0, date);
}
}
public class DateListItemReader<T> extends AbstractItemStreamItemReader<T>
{
List<Date> dateList;
int listIndex = -1;
DateListPreparedStatementSetter pss;
ItemReader<T> delegate;
public void setDateList(List<Date> dateList) {
this.dateList = dateList;
}
public void setDelegate(ItemReader<T> delegate) {
this.delegate = delegate;
}
public void setPss(DateListPreparedStatementSetter pss) {
this.pss = pss;
}
public T read() throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {
T next = delegate.read();
// No more elements...
if(null == next)
{
// Close delegate
++listIndex;
// ...but more dates!
if(listIndex < dateList.size())
{
pss.setDate(dateList.get(listIndex));
// Open delegate
// Recursive read
next = read();
}
}
return next;
}
@Override
public void open(ExecutionContext executionContext) {
// Restore last index
listIndex = executionContext.getInt("dateListIndex",-1);
((ItemStream)delegate).open(executionContext);
super.open(executionContext);
}
@Override
public void update(ExecutionContext executionContext) {
// Save last index
executionContext.putInt("dateListIndex", listIndex);
((ItemStream)delegate).update(executionContext);
super.update(executionContext);
}
@Override
public void close() {
((ItemStream)delegate).close();
super.close();
}
}
<bean name="myPSS" class="DateListPreparedStatementSetter" />
<bean name="myReader" class="DateListItemReader">
<property name="dateList">
<list>
<value>01/01/2010</value>
<value>01/01/2011</value>
</list>
</property>
</bean>
<bean name="MyItemReader">
<!-- Other props... ->
<property name="preparedStatementSetter" ref="myPSS" />
</bean>
我没有测试过代码,但这个想法应该很明确。
答案 1 :(得分:1)