Java 结果集元数据作为Spring批处理中CSV文件的头
我正在编写一个代码,从SQL存储过程的结果集生成CSV文件。通过使用Spring批处理框架本身,我几乎使所有内容都通用,但头除外。我希望resultset的元数据作为头。我不想扩展Java 结果集元数据作为Spring批处理中CSV文件的头,java,spring-batch,Java,Spring Batch,我正在编写一个代码,从SQL存储过程的结果集生成CSV文件。通过使用Spring批处理框架本身,我几乎使所有内容都通用,但头除外。我希望resultset的元数据作为头。我不想扩展StoredProcedureItemReader并执行它。在Spring批处理框架中是否有任何类/项可以像我上面问的那样编写头,或者在StoredProcedureItemReader或FlatFileItemWriter中是否有任何属性可以执行此操作。我希望它是通用的,因为我希望对多个存储过程使用相同的代码。spr
StoredProcedureItemReader
并执行它。在Spring批处理框架中是否有任何类/项可以像我上面问的那样编写头,或者在StoredProcedureItemReader
或FlatFileItemWriter
中是否有任何属性可以执行此操作。我希望它是通用的,因为我希望对多个存储过程使用相同的代码。spring Batch提供了创建文件头的FlatFileHeaderCallback
。
您需要实现writeHeader(Writer-Writer)
方法
在WriteHeader方法中,您需要编写如下内容
1在该类中注入JdbcTemplate
然后
List List=jdbcTemplate.query(“从1=2的表中选择*,新建YourMapper())
在映射器中-从ResultSet
对象可以获得ResultSetMetaData
*。
现在使用ResultSetMetaData
可以获得所有列名的列表。
然后从mapper返回此列表,spring Batch提供了用于创建文件头的FlatFileHeaderCallback。 您需要实现
writeHeader(Writer-Writer)
方法
在WriteHeader方法中,您需要编写如下内容
1在该类中注入JdbcTemplate
然后
List List=jdbcTemplate.query(“从1=2的表中选择*,新建YourMapper())
在映射器中-从ResultSet
对象可以获得ResultSetMetaData
*。
现在使用ResultSetMetaData
可以获得所有列名的列表。
然后从映射器返回此列表实现
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());
}
}
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;
}
}
公共类TestClass实现FlatFileHeaderCallback{
@自动连线
私有JdbcTemplate JdbcTemplate;//如果您有JdbcTemplate bean或使用数据源,请运行SQL
@凌驾
public void writeHeader(Writer-Writer)引发IOException{
List List=jdbcTemplate.query(“从表中选择*,其中1=2”,新建YourMapper());
list.toString();
writer.write(list.toString());
}
}
映射器将是这样的
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());
}
}
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;
}
}
public类YourDBMapper实现ResultSetExtractor{
列表=新列表();
@凌驾
公共列表提取数据(结果集rs){
ResultSetMetaData meta=rs.getMetaData();
对于(int i=1;i实现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());
}
}
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;
}
}
公共类TestClass实现FlatFileHeaderCallback{
@自动连线
私有JdbcTemplate JdbcTemplate;//如果您有JdbcTemplate bean或使用数据源,请运行SQL
@凌驾
public void writeHeader(Writer-Writer)引发IOException{
List List=jdbcTemplate.query(“从表中选择*,其中1=2”,新建YourMapper());
list.toString();
writer.write(list.toString());
}
}
映射器将是这样的
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());
}
}
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;
}
}
public类YourDBMapper实现ResultSetExtractor{
列表=新列表();
@凌驾
公共列表提取数据(结果集rs){
ResultSetMetaData meta=rs.getMetaData();
对于(inti=1;i实际上,我的代码中有如下内容来获取元数据
@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;
}
请查看我的作业配置
<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>
实际上,我的代码中有如下内容来获取元数据
@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;
}
请查看我的作业配置
<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>
感谢您的快速响应。数据库读取器已经执行了查询并返回了结果集,因此我可以在不使用jdbcTemplate的情况下获取一些内容吗?我不能从读取器本身获取结果集吗?您需要创建一个自定义的ItemReader
,将元数据提取到ExecutionContext
中,以便它是一个可跨组件使用。Vishal如果不想再次运行查询,则需要自定义ItemReader并向ExecutionContext添加Michael提到的元数据。在writeHeader方法中使用此ExecutionContext。如果答案有帮助,请接受它,以便其他人也可以使用相同的方法。实际上,我尝试在rowmapper中获取元数据一次。但是只有在写下标题后才会调用。你能给我一些关于这个的示例吗?添加了一些示例代码,请检查单独的答案谢谢你的快速响应。我可以不使用jdbcTemplate获取一些内容吗?因为数据库读取器已经执行了查询并返回了结果集。我不能从reade获取结果集吗r本身。您需要创建一个自定义的ItemReader
,将元数据提取到ExecutionContext
中,以便跨组件提供元数据。Vishal如果您不想再次运行查询,则需要自定义ItemReader并向ExecutionContext添加Michael提到的元数据。使用此executioncontentxt在writeHeader方法中。如果答案帮助您,请接受它,这样其他人也可以使用相同的方法。实际上,我曾尝试在rowmapper中获取元数据。但这只有在写下标题后才调用。您能给我一些关于这方面的示例吗。添加了一些示例代码,请检查单独的答案