结果集元数据作为Spring批处理中CSV文件的标题

时间:2017-06-23 10:52:35

标签: java spring-batch

我正在编写一个代码,用于从SQL存储过程的结果集生成CSV文件。我通过使用Spring Batch框架本身几乎所有的通用,但除了header.I希望结果集的元数据作为标题。我不想延长StoredProcedureItemReader并执行此操作。 Spring Batch框架中是否有任何类/项目来编写我上面提到的标题,或者StoredProcedureItemReaderFlatFileItemWriter中是否有任何属性来执行此操作。我希望它是通用的,因为我想对多个存储过程使用相同的代码。

3 个答案:

答案 0 :(得分:0)

spring Batch提供FlatFileHeaderCallback来创建文件头。 您需要实现writeHeader(Writer writer)方法。

在WriteHeader方法中,您需要编写类似这样的东西。

1在该类中注入JdbcTemplate

然后

List<ColumList> list = jdbcTemplate.query("Select * From table where 1=2",new YourMapper()) 

在Mapper中 - 来自ResultSet对象,您可以获得ResultSetMetaData *。 现在使用ResultSetMetaData,您可以获得所有 ColumnNames 的列表。 然后从mapper

返回此列表

答案 1 :(得分:0)

像这样实施FlatFileHeaderCallback

public class TestClass implements FlatFileHeaderCallback  {

    @Autowired
    private JdbcTemplate jdbcTemplate; //IF you have jdbcTemplate bean or use data source run the SQL


    @Override
    public void writeHeader(Writer writer) throws IOException {


        List<String> list = jdbcTemplate.query("Select * From table where 1=2",new YourMapper()) ;
        list.toString();
        writer.write(list.toString());      
    }

}

Mapper将是这样的

public class YourDBMapper implements ResultSetExtractor<List<String>> {

    List<String> list = new List<>();
    @Override
    public List<String> extractData(ResultSet rs){      

        ResultSetMetaData meta = rs.getMetaData();    

        for (int i = 1; i <=  meta.getColumnCount(); i++) 
            list.add(meta.getColumnName(i));        

        return list;
    }

}

希望这有帮助

答案 2 :(得分:0)

实际上我的代码中有类似下面的内容来获取元数据

    @Scope("step")
    public class CustomColumnMapRowMapper extends ColumnMapRowMapper{
    private static boolean isMetadataSet = false;
    @Autowired
    private StepExecution stepExecution;
    @Autowired
    private String delimiter;

    private String metadata="";
    @Override
    public Map<String, Object> mapRow(ResultSet rs, int rowNum) throws SQLException {
        System.out.println("Inside custom row mapper "+this.getClass().getName());
        ResultSetMetaData rsmd = rs.getMetaData();

        int columnCount = rsmd.getColumnCount();
        Map<String, Object> mapOfColValues = createColumnMap(columnCount);
        for (int i = 1; i <= columnCount; i++) {
            String key = getColumnKey(JdbcUtils.lookupColumnName(rsmd, i));
            if(!this.isMetadataSet){
                if(i==columnCount){
                    metadata=metadata.concat(key);
                    break;
                }
                metadata=metadata.concat(key).concat(delimiter);
            }
            Object obj = getColumnValue(rs, i);
            mapOfColValues.put(key, obj);
        }
        if(!this.isMetadataSet){
            this.stepExecution.getJobExecution().getExecutionContext().put("metadata", this.metadata);
            this.isMetadataSet = true;
            System.out.println("Metadata retrieved is "+this.stepExecution.getJobExecution().getExecutionContext().get("metadata"));
        }

        //System.out.println("Metadata is "+this.metadata);
        return mapOfColValues;
    }

它正在工作,但这里的问题是在上面的rowmapper之前调用了header。请参阅下面的CustomFlatFileHeader

public class CustomFlatFileHeader implements FlatFileHeaderCallback{

    @Autowired
    private StepExecution stepExecution;

    @Override
    public void writeHeader(Writer writer) throws IOException {
        System.out.println("Metdata in col header");
        writer.write(this.stepExecution.getJobExecution().getExecutionContext().get("metadata").toString());
    }

    public StepExecution getStepExecution() {
        return stepExecution;
    }

    public void setStepExecution(StepExecution stepExecution) {
        System.out.println("Inside step exec setting ");
        this.stepExecution = stepExecution;
    }
}

请参阅我的工作配置

<batch:job id="ReportJob">
    <batch:step id="step1">
        <batch:tasklet transaction-manager="transactionManager">
            <batch:chunk reader="databaseItemReader" writer="flatFileItemWriter"
                processor="itemProcessor" commit-interval="100" />
        </batch:tasklet>
    </batch:step>
    <batch:listeners>
        <batch:listener ref="jobListener" />
    </batch:listeners>
</batch:job>