Spring Batch中ItemWriter未执行时,如何验证数据库是否拉取到数据?
问题描述
参考数据库读取打印列表的示例实现Spring Batch任务,目前能看到ItemReader和ItemWriter的初始化日志,但LoggingItemWriter的write方法未执行,想验证数据库是否成功拉取到数据。
我的Batch配置代码
@Configuration @EnableBatchProcessing public class BatchConfing { private static final String QUERY_FIND_STUDENTS = "select " + "stu_info " + "from myTable " + "where status = '\"+PASS + \"" ; @Bean public ItemReader<StudentDTO> itemReader(DataSource dataSource) { System.out.println("Reached Reader"); return new JdbcCursorItemReaderBuilder<StudentDTO>() .name("cursorItemReader") .dataSource(dataSource) .sql(QUERY_FIND_STUDENTS) .rowMapper(new BeanPropertyRowMapper<>(StudentDTO.class)) .build(); } @Bean public ItemWriter<StudentDTO> itemWriter(){ System.out.println("I am in writer"); return new LoggingItemWriter(); /* return student -> { System.out.println("student.toString()"); };*/ } @Bean public JobExecutionListener listener() { return new ScheduelListener(); } @Bean public Step stepA(@Qualifier("itemReader") ItemReader<StudentDTO> reader, @Qualifier("itemWriter") ItemWriter<StudentDTO> writer, StepBuilderFactory stepBuilderFactory) { return stepBuilderFactory.get("stepA") .<StudentDTO,StudentDTO>chunk(2) .reader(reader) .writer(writer) .build() ; } @Bean public Job jobA(@Qualifier("stepA") Step exampleJobStep, JobBuilderFactory jobBuilderFactory){ return jobBuilderFactory.get("jobA") .incrementer(new RunIdIncrementer()) .listener(listener()) .flow(exampleJobStep) .end() .build() ; } }
LoggingItemWriter代码
public class LoggingItemWriter implements ItemWriter<StudentDTO> { public LoggingItemWriter() { System.out.println("test LoggingItemWriter "); } private static final Logger LOGGER = LoggerFactory.getLogger(LoggingItemWriter.class); @Override public void write(List<? extends StudentDTO> list) throws Exception { LOGGER.info("Writing student info: {}", list); for (StudentDTO item : list) { System.out.println("test"+list); } } }
验证数据库数据拉取的方法
- 直接调试Reader读取逻辑:在
itemReader方法中临时添加手动读取测试,验证是否能获取数据:@Bean public ItemReader<StudentDTO> itemReader(DataSource dataSource) { System.out.println("Reached Reader"); JdbcCursorItemReader<StudentDTO> reader = new JdbcCursorItemReaderBuilder<StudentDTO>() .name("cursorItemReader") .dataSource(dataSource) .sql(QUERY_FIND_STUDENTS) .rowMapper(new BeanPropertyRowMapper<>(StudentDTO.class)) .build(); // 临时测试读取逻辑 try { reader.open(new ExecutionContext()); StudentDTO dto; while ((dto = reader.read()) != null) { System.out.println("读取到数据:" + dto); } reader.close(); } catch (Exception e) { e.printStackTrace(); } return reader; } - 修复SQL语句错误:当前SQL拼接存在语法问题,
"where status = '\"+PASS + \""会生成无效SQL,改用参数化查询避免错误:
SQL语法错误会导致查询无结果,Reader返回空数据,此时Writer的private static final String QUERY_FIND_STUDENTS = "select stu_info from myTable where status = ?"; // 构建Reader时设置参数 return new JdbcCursorItemReaderBuilder<StudentDTO>() .name("cursorItemReader") .dataSource(dataSource) .sql(QUERY_FIND_STUDENTS) .parameterValues(PASS) // 传入PASS变量的实际值 .rowMapper(new BeanPropertyRowMapper<>(StudentDTO.class)) .build();write方法不会被触发。 - 开启Spring Batch DEBUG日志:将日志级别调整为DEBUG,Spring Batch会打印Step执行统计、Reader读取记录数等详细信息,直接确认是否读取到数据。
- 临时替换Writer测试:把
itemWriter中的返回逻辑换回你注释掉的匿名内部类,如果能打印内容,说明LoggingItemWriter的日志配置存在问题;如果仍无输出,说明Reader未读取到数据。
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

