从高层次来看,我的申请流程似乎是
REST控制器RequestMapping由GET()请求触发。 REST控制器调用Service类中的方法。
@RequestMapping(value="/eventreports", method = RequestMethod.POST, produces = "application/json")
public @ResponseBody List<EventReports> addReportIds(@RequestBody List<Integer> reportIds) {
List<EventReports> eventReports = railAgentCollectorServiceImpl.addReportIds(reportIds);
return eventReports;
}
服务方法在DAO类中调用方法。
@Override
public List<EventReports> addReportIds(List<Integer> reportIds) {
List<EventReports> eventReports = eventReportsDAOImpl.listEventReportsInJsonRequest(reportIds);
return eventReports;
}
DAO方法针对SQL数据源执行StoredProcedureQuery,该数据源将结果作为域对象的ArrayList返回。 Service类将域对象的Arraylist传递回REST Controller,REST Controller将域对象的ArrayList作为JSON字符串返回。
@Override
public List<EventReports> listEventReportsInJsonRequest(List<Integer> reportIds) {
ArrayList<EventReports> erArr = new ArrayList<EventReports>();
try {
StoredProcedureQuery q = em.createStoredProcedureQuery("sp_get_event_reports", "eventReportsResult");
q.registerStoredProcedureParameter("reportIds", String.class, ParameterMode.IN);
q.setParameter("reportIds", reportIdsList);
boolean isResultSet = q.execute(); //try catch here
erArr = (ArrayList<EventReports>) q.getResultList();
} catch (Exception e) {
System.out.println("No event reports found for list " + reportIdsList);
}
return erArr;
}
我一直在研究将Spring Batch处理集成到上面的模式中。我一直在寻找批量处理的Spring入门指南https://spring.io/guides/gs/batch-processing/ - 特别注意BatchConfiguration.java的源代码 - 我不确定我的应用程序是否适合Spring Batch,也许我不完整的知识Spring Batch及其实现的各种方式阻碍了我对它的概念化。下面的BatchConfiguration.java代码告诉我,Spring Batch可能最适合迭代项目列表,逐个读取它们,逐个处理它们,然后逐个编写它们 - 而我的服务代码基于一次收集和写入对象列表。
@Bean
public FlatFileItemReader<Person> reader() {
FlatFileItemReader<Person> reader = new FlatFileItemReader<Person>();
reader.setResource(new ClassPathResource("sample-data.csv"));
reader.setLineMapper(new DefaultLineMapper<Person>() {{
setLineTokenizer(new DelimitedLineTokenizer() {{
setNames(new String[] { "firstName", "lastName" });
}});
setFieldSetMapper(new BeanWrapperFieldSetMapper<Person>() {{
setTargetType(Person.class);
}});
}});
return reader;
}
@Bean
public PersonItemProcessor processor() {
return new PersonItemProcessor();
}
@Bean
public JdbcBatchItemWriter<Person> writer() {
JdbcBatchItemWriter<Person> writer = new JdbcBatchItemWriter<Person>();
writer.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<Person>());
writer.setSql("INSERT INTO people (first_name, last_name) VALUES (:firstName, :lastName)");
writer.setDataSource(dataSource);
return writer;
}
// end::readerwriterprocessor[]
// tag::jobstep[]
@Bean
public Job importUserJob(JobCompletionNotificationListener listener) {
return jobBuilderFactory.get("importUserJob")
.incrementer(new RunIdIncrementer())
.listener(listener)
.flow(step1())
.end()
.build();
}
@Bean
public Step step1() {
return stepBuilderFactory.get("step1")
.<Person, Person> chunk(10)
.reader(reader())
.processor(processor())
.writer(writer())
.build();
}
这是真的吗?我还能利用Spring Batch为现有代码提供的恢复能力,调度和同步吗?任何建议表示赞赏。
答案 0 :(得分:0)
我认为您需要考虑这种同步行为和异步行为。批处理过程用于长时间运行的任务,所以,
考虑你的任务是否长期运行。如果您的任务长时间运行,您可以使用批处理。这将是异步的,因为您的请求进入并启动任务,然后回复给用户。
批处理将运行并完成并将结果写回数据库,用户必须使用ajax轮询结果,或者您可能必须实现推送通知机制来处理异步行为的任务状态/阻止民意调查。
答案 1 :(得分:0)
真正的是一个由读者组成的Spring Batch块 - &gt;处理器 - &gt;编写者读取一个项目,处理一个项目,但根据定义的块大小写入一大块项目。
因此,根据您定义的 chunk_size ,您可以一次性发送数千个项目给作者写入存储空间。
话虽如此,读者只读了一个项目,但没有必要从源(从文件/数据库等)本身只读取一个项目。有些读者可以从源头一次读取大量的项目,将其自身保存在列表中并逐个移交给处理器,直到列表用完为止。
其中一个读者是JdbcPagingItemReader,例如它按照定义的阅读器一次从数据库读取几千行 page_size (显着减少了DB调用),然后一个接一个地交给处理器,然后处理器自动保持累积处理后的输出直到 chunk_size ,然后批量交给作家。
它只是另一种情况,即你的API中的要求可能没有现成的东西 - 在这种情况下,你必须编写自己的ItemReader
。
查看JdbcPagingItemReader
的代码以获取想法。
对于你的情况,Spring Batch的编写者根本不是一个问题,它只是通过简单的配置批量编写。您必须将Controller的输出提供给阅读器,阅读器的作用与JdbcPagingItemReader
类似。
我只想说内存处理是一个接一个(而且速度非常快),但IO可以在春季批量中批量完成(如果你选择的话)。
希望它有所帮助!!