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