Spring Batch动态多个xml文件编写器

时间:2015-01-19 10:45:28

标签: xml output spring-batch partitioner

我必须做一批: 从DB读取一些数据(每行是一个项目,这很好)
然后做一些过程来添加更多的数据(更多的数据总是更好;)) 那么这是我的问题,我必须在xml文件中写下每个项目,其名称取决于项目的数据。

例如我有 ItemA(attr1 = toto,attr2 = foo,attr3 = myNonKeyData ...)=>进入toto_foo.xml
ItemB(attr1 = toto,attr2 = foo,attr3 = myNonKeyData ...)=>进入toto_foo.xml

ItemC(attr1 = tata,attr2 = foo ...)=>进入tata_foo.xml
......

我只能在一次批次运行中看不到如何做到这一点 我有太多的键和可能的输出文件来做分类器 也许使用分区器可能是一个好主意,即使它似乎不是为此而设计的。

1 个答案:

答案 0 :(得分:4)

这是我所理解的。

  • 任意数量的文件。
  • 一次性从DB处理数据 - 从DB读取一次并写入多个文件。
  • 正在编写的项目的一个或多个属性确定要写入的目标文件的名称。

创建一个复合ItemWriter(受org.springframework.batch.item.support.CompositeItemWriter启发)。这是一些伪代码

public class MyCompositeItemWriter<T> implements ItemStreamWriter<T> {

// The String key is the file-name(toto_foo.xml, tata_foo.xml etc)
//The map will be empty to start with as we do not know how many files will be created. 
private Map<String, ItemWriter<? super T>> delegates;

private boolean ignoreItemStream = false;

public void setIgnoreItemStream(boolean ignoreItemStream) {
    this.ignoreItemStream = ignoreItemStream;
}

@Override
public void write(List<? extends T> items) throws Exception {

    for(T item : items) {
        ItemWriter<? super T> writer = getItemWriterForItem(item);
        // Writing one item ata time might be inefficent. You can optimize this by grouping items by fileName. 
        writer.write(item);     
    }       
}


private getItemWriterForItem(T item) {
    String fileName = getFileNameForItem(item); 
    ItemWriter<? super T> writer = delegates.get(fileName);
    if(writer == null) {
        // There is no writer for the fileName. 
        //create one
        writer = createMyItemWriter(fileName);
        delegates.put(fileName, writer);
    }
    return writer;
}

ItemWriter<? super T> createMyItemWriter(String fileName) {
    // create the writer. Maybe a org.springframework.batch.item.xml.StaxEventItemWriter 
    // set the resource(fielName)
    //open the writer
}




// Identify the name of the target file - toto_foo.xml, tata_foo.xml etc
private String getFileNameForItem(Item item) {
    .....
}

@Override
public void close() throws ItemStreamException {
    for (ItemWriter<? super T> writer : delegates) {
        if (!ignoreItemStream && (writer instanceof ItemStream)) {
            ((ItemStream) writer).close();
        }
    }
}

@Override
public void open(ExecutionContext executionContext) throws ItemStreamException {
    // Do nothing as we do not have any writers to begin with. 
    // Writers will be created as needed. And will be opened after creation. 
}

@Override
public void update(ExecutionContext executionContext) throws ItemStreamException {
    for (ItemWriter<? super T> writer : delegates) {
        if (!ignoreItemStream && (writer instanceof ItemStream)) {
            ((ItemStream) writer).update(executionContext);
        }
    }
}