【问题标题】:How to write csv file with empty body using Spring batch如何使用 Spring 批处理编写带有空正文的 csv 文件
【发布时间】:2017-07-02 08:02:28
【问题描述】:

我正在使用 Spring Boot 编写我的出站批处理,其中一项要求是仅在未找到记录时才发送并清空带有标题的文件。

我使用 BeanPropertyRowMapper 来映射我的 JdbcCursorItemReader...为什么我使用 BeanPropertyRowMapper 因为有很多列要映射。如果我使用 rowmapper,那对我来说将是地狱,哈哈。这是配置:

    @Bean
public Step RawDataOutBoundSteps() throws IOException {

    return stepBuilderFactory.get("step1").<RawDataExtractionDTO, RawDataExtractionDTO>chunk(1000)//.faultTolerant()
            //.skip(Exception.class)
            //.skipLimit(1000)
            .reader(myDBReader()).processor(myProcessor())
            .writer(myWriter()).build();
}

问题是,如果 myDBreader() 查询返回空结果集,我的代码不会转到 myProcessor,因此也不会转到 myWriter。

我的处理器:

public class RawDataJobProcessor implements 
ItemProcessor<RawDataExtractionDTO, RawDataExtractionDTO>{

@Override
public RawDataExtractionDTO process(RawDataExtractionDTO item) throws Exception {
    System.out.println(" Raw DAta Process");

    if(item == null )
    return null;

    return item;
}}

我的数据库阅读器:

    @Bean
ItemReader<RawDataExtractionDTO> rawDataDBReader() {

    String jobName = Application.jobName;
    String sql_query = "";

    if("RawDataOutBoundweekly".equalsIgnoreCase(jobName)){
        log.info("=========RawDataOutBoundweekly=========");

        sql_query = "select * from vw_rawdata_weekly";

    }else if("RawDataOutBoundmonthly".equalsIgnoreCase(jobName)){
        log.info("================RawDataOutBoundmonthly=============");

        sql_query = "select * from vw_rawdata_monthly";
    }
    log.info("ENTERING rawDataDBReader  ===================");


    JdbcCursorItemReader<RawDataExtractionDTO> datareader = new 
    JdbcCursorItemReader<>();
    datareader.setSql(sql_query);
    datareader.setDataSource(dataSource);
    datareader.setRowMapper(new BeanPropertyRowMapper<>
    (RawDataExtractionDTO.class));
    return datareader;
}

没有错误抛出,但如果我将调试点放在阅读器之后,它根本不会进入我的处理器,它只会关闭作业。

【问题讨论】:

    标签: spring-boot spring-batch


    【解决方案1】:

    你可以实现FlatFileHeaderCallback来写文件头。

    http://docs.spring.io/spring-batch/apidocs/org/springframework/batch/item/file/FlatFileHeaderCallback.html

    一些配置FlatFileHeaderCallback的示例代码。即使阅读器没有读取任何记录 FlatFileHeaderCallback 也会被调用并写入标题。最终文件将只有标题

    @Bean
        public FlatFileItemWriter<Person> myWriter()
        {
            System.out.println("FlatFileItemWriter*******************");
            FlatFileItemWriter<Person> writer = new FlatFileItemWriter<Person>();
            writer.setResource(new FileSystemResource("output.csv"));
            DelimitedLineAggregator<Person> delLineAgg = new DelimitedLineAggregator<Person>();
            delLineAgg.setDelimiter(",");
            BeanWrapperFieldExtractor<Person> fieldExtractor = new BeanWrapperFieldExtractor<Person>();
            fieldExtractor.setNames(new String[] {"firstName", "lastName"});
            delLineAgg.setFieldExtractor(fieldExtractor);
            writer.setLineAggregator(delLineAgg);
    
       writer.setHeaderCallback(myFlatFileHeaderCallback);      
    
    
            return writer;
        }
    
    
    @Component
    public class MyFlatFileHeaderCallback implements FlatFileHeaderCallback {
    
        @Override
        public void writeHeader(Writer writer) throws IOException {
            System.out.println("Header called");
    
        }
    
    }
    

    【讨论】:

    • 问题不在于如何编写标题,问题是,如果我的读者返回空结果集,我永远不会去找我的作家,因为我的作家已经拥有一切,如果结果很好集合不为空
    • 即使阅读器没有读取任何行,仍然调用 FlatFileHeaderCallback.writeHeader 方法。我做了一个小测试程序,即使有行数据读写,我的 writeHeader 方法也会被调用
    • 我不得不更改我的实现,因为之前我只是编写了一个新类并实现了 flatfileHeaderCallBack。在我根据您的代码直接实现 itemwriter 之后,只有我的标题来了。谢谢你,先生。
    猜你喜欢
    • 2020-01-27
    • 2023-03-03
    • 2011-02-03
    • 2022-07-04
    • 2013-11-21
    • 1970-01-01
    • 2015-07-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多