Springbatch динамический множественный писатель XML-файлов
Я должен сделать партию, которая:
читать некоторые данные из БД (каждая строка является элементом, это нормально)
затем выполните некоторый процесс, чтобы добавить больше данных (больше данных всегда лучше;))
тогда вот моя проблема, я должен записать каждый элемент в 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 ответ
Это то, что я понял.
- Произвольное количество файлов.
- Обработка данных из БД за один проход - чтение из БД один раз и запись в несколько файлов.
- Один или несколько атрибутов записываемого элемента определяют имя целевого файла для записи.
Создайте составной 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);
}
}
}