2

私はバッチを実行する必要があります:
DBからいくつかのデータを読み取り(各行はアイテムです、これは問題
ありません)、さらにデータを追加するプロセスを実行します(より多くのデータは常に優れています;))
次に、ここに私の問題があります。名前がアイテムのデータに依存するxmlファイルに各アイテムを書き込む。

たとえば、私は
ItemA (attr1=toto, attr2=foo, attr3=myNonKeyData...)=>goes in toto_foo.xml
ItemB (attr1=toto, attr2=foo, attr3=myNonKeyData...)=>toto_foo に入る.xml

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

1回のバッチ実行でこれを行う方法がわかりません。
分類子を実行するには、キーと可能な出力ファイルが多すぎます。
そのために設計されていないように見えても、パーティショナーを使用することは良い考えかもしれません。

4

1 に答える 1

5

これが私が理解したことです。

  • 任意の数のファイル。
  • DB からのデータを 1 回のパスで処理 - DB から 1 回読み取り、複数のファイルに書き込みます。
  • 書き込まれる項目の 1 つ以上の属性によって、書き込み先のターゲット ファイルの名前が決まります。

複合 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);
        }
    }
}
于 2015-01-19T21:40:47.337 に答える