我有一个DAO类来从Hibernate中检索一组数据。
<batch:step id="firstStep">
<batch:tasklet>
<batch:chunk reader="firstReader" writer="firstWriter"
processor="itemProcessor" commit-interval="2">
</batch:chunk>
</batch:tasklet>
</batch:step>
<bean id="firstReader" class="com.process.MyReader"
scope="step">
</bean>
在我的读者中,我会在读取之前调用DAO来获取数据。
public class MyReader implements ItemReader<JobInstance>{
private List<JobInstance> jobList;
private String currentDate;
@Autowired
private JobDAO perDAO;
@BeforeRead
public void init() {
//jobList= perDAO.getPersonAJobList(currentDate);
}
@Override
public JobInstance read() throws Exception, UnexpectedInputException,
ParseException, NonTransientResourceException {
return !jobList.isEmpty() ? jobList.remove(0) : null;
}
@Value("#{jobParameters['currentDate']}")
public void setCurrentDate(String currentDate) {
this.currentDate = currentDate;
}
@Override
public void beforeStep(StepExecution stepExecution) {
// TODO Auto-generated method stub
}
@Override
public ExitStatus afterStep(StepExecution stepExecution) {
// TODO Auto-generated method stub
return null;
}
}
当我运行批处理作业时,批处理作业会不断重复读取和处理。
[org.springframework.batch.repeat.support.RepeatTemplate] [getNextResult] [372] - Repeat operation about to start at count=1
以下是我的DAO课程
@Autowired
private QueryManager queryManager;
@Autowired
public JobDAO Impl(SessionFactory sessionFactory) {
super(sessionFactory, JobInstance.class);
}
public List<JobInstance> getPersonAJobList(String currentDate) {
String sql = queryManager.getNamedQuery("getJobList");
System.out.println("---------------------- " + sql + " " + currentDate);
SQLQuery query = this.getCurrentSession().createSQLQuery(sql);
query.setParameter("current_date", currentDate);
....
return result;
}
答案 0 :(得分:0)
如果你在@BeforeRead注释方法中填写列表,那么列表将在每次读取之前更新
请参阅http://docs.spring.io/spring-batch/apidocs/org/springframework/batch/core/annotation/BeforeRead.html
Marks a method to be called before an item is read from an ItemReader
如果您需要从DAO获取项目,则需要考虑
的实现更好的方法是将数据访问(SQL)移动到批处理中,Spring Batch为SQL,Hibernate等提供了开箱即用的读者...请参阅http://docs.spring.io/spring-batch/reference/html/listOfReadersAndWriters.html
答案 1 :(得分:0)
init方法只应调用一次。执行此操作的正确方法是实现InitializingBean接口并实现afterPropertiesSet方法,或使用@PostConstruct注释而不是@BeforeRead。
使用@BeforeRead绝对是错误的,毫无意义。
正如Michael对答案的评论中所提到的,您还应该考虑使用标准读取器之一来从db获取数据。如果你从getPersonAJobList中获得几百或几千个条目就不会有问题,但是如果你得到数百万个条目,那肯定是错误的方法。
答案 2 :(得分:0)
如何在阅读器中添加“init”标志?进入MyReader.read()
:
jobDAO
以填充jobList
并设置标记jobList
个项目。小心使用jobList.remove(0)
,因为您的阅读器似乎无法重启;您需要将最后使用的项目索引维护到执行上下文中,以便从最后一个未提交的块的第一项继续重新启动。