Java Spring批处理是否适合我的服务代码?
从较高的层次来看,我的应用程序流如下所示 REST控制器RequestMapping由GET()请求触发。REST控制器调用服务类中的方法Java Spring批处理是否适合我的服务代码?,java,spring,spring-batch,Java,Spring,Spring Batch,从较高的层次来看,我的应用程序流如下所示 REST控制器RequestMapping由GET()请求触发。REST控制器调用服务类中的方法 @RequestMapping(value="/eventreports", method = RequestMethod.POST, produces = "application/json") public @ResponseBody List<EventReports> addReportIds(@RequestBody List<I
@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;
}
@RequestMapping(value=“/eventreports”,method=RequestMethod.POST,products=“application/json”)
public@ResponseBody List addReportIds(@RequestBody List reportIds){
List eventReports=railAgentCollectorServiceImpl.AddReportId(ReportId);
返回事件报告;
}
服务方法调用DAO类中的方法
@Override
public List<EventReports> addReportIds(List<Integer> reportIds) {
List<EventReports> eventReports = eventReportsDAOImpl.listEventReportsInJsonRequest(reportIds);
return eventReports;
}
@覆盖
公共列表AddReportId(列表ReportId){
List eventReports=eventReportsDAOImpl.ListentReportsInJSonRequest(ReportId);
返回事件报告;
}
DAO方法对SQL数据源执行StoredProcedureRequest,该SQL数据源将结果作为域对象的ArrayList返回。服务类将这个域对象的Arraylist传递回REST控制器,REST控制器以JSON字符串的形式返回域对象的Arraylist
@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;
}
@覆盖
公共列表ListVentReportsInJSonRequest(列表报告ID){
ArrayList erArr=新的ArrayList();
试一试{
StoredProcedureQuery q=em.createStoredProcedureQuery(“sp_获取事件报告”、“事件报告结果”);
q、 registerStoredProcedureParameter(“ReportId”,String.class,ParameterMode.IN);
q、 setParameter(“reportIds”,reportIdsList);
boolean isResultSet=q.execute();//在此处尝试catch
erArr=(ArrayList)q.getResultList();
}捕获(例外e){
System.out.println(“未找到列表的事件报告”+reportIdsList);
}
返回erArr;
}
我一直在研究将Spring批处理集成到上述模式中。我一直在看Spring批处理入门指南-特别关注BatchConfiguration.java的源代码-我不确定我的应用程序是否适合Spring批处理,也许我对SpringBatch及其各种实现方式的不完全了解妨碍了我对它的概念化。下面的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();
}
@Bean
公共FlatFileItemReader()读取器{
FlatFileItemReader=新的FlatFileItemReader();
setResource(新类路径资源(“sample data.csv”);
reader.setLineMapper(新的DefaultLineMapper(){{
setLineTokenizer(新的DelimitedLineTokenizer(){{
setNames(新字符串[]{“firstName”,“lastName”});
}});
setFieldSetMapper(新的BeanRapperFieldSetMapper(){{
setTargetType(Person.class);
}});
}});
返回读取器;
}
@豆子
公共PersonItemProcessor处理器(){
返回新的PersonItemProcessor();
}
@豆子
公共JdbcBatchItemWriter编写器(){
JdbcBatchItemWriter writer=新的JdbcBatchItemWriter();
writer.setItemSqlParameterSourceProvider(新的BeanPropertyItemSqlParameterSourceProvider());
setSql(“插入人(名字、姓氏)值(:firstName,:lastName)”;
writer.setDataSource(dataSource);
返回作者;
}
//end::readerwriterprocessor[]
//标记::作业步骤[]
@豆子
公共作业导入器作业(作业完成通知侦听器侦听器){
返回jobBuilderFactory.get(“importUserJob”)
.incrementer(新的RunIdIncrementer())
.listener(侦听器)
.flow(步骤1())
(完)
.build();
}
@豆子
公共步骤第1步(){
返回stepBuilderFactory.get(“step1”)
.chunk(10)
.reader(reader())
.processor(处理器())
.writer(writer())
.build();
}
这是真的吗?我是否仍然可以利用SpringBatch为我现有代码提供的恢复功能、调度和同步功能?有任何建议值得赞赏。 < P>我认为你需要考虑的是同步行为和异步行为。批处理用于长时间运行的任务,因此 考虑您的任务是否需要长期运行。如果任务长时间运行,则可以使用批处理。这将是异步的,因为您的请求进入并启动任务,然后响应用户
批处理将运行并完成,并将结果写回数据库,用户将不得不使用Ajax对结果进行投票,或者您可能需要执行推送通知机制来处理异步行为/阻止轮询的任务状态。 < P>我认为您需要考虑同步行为和异步行为。批处理用于长时间运行的任务,因此 考虑您的任务是否需要长期运行。如果任务长时间运行,则可以使用批处理。这将是异步的,因为您的请求进入并启动任务,然后响应用户
批处理将运行并完成,并将结果写回数据库,用户必须使用ajax轮询结果,或者您可能必须实现推送通知机制来处理异步行为/阻止轮询的任务状态。由读卡器->处理器->写卡器组成的Spring批处理块确实读取一项,处理一个项目,但根据定义的区块大小写入项目区块 因此,根据您定义的块大小,您可以一次将数千个项目发送到写入器以写入存储 话虽如此,读卡器读取一项内容,但不必仅从源代码(从文件/DB等)读取一项内容。有些阅读器可以从源代码一次读取大量项目,并将其保存在lis中