我有一个批处理作业,它从数据库中检索记录,处理它们,然后将结果传递给编写器。传递给编写器的 bean 有四个字段需要写入单独的 xml 文件。其中一个字段是代表原始记录的 bean,其他三个字段是与该记录关联的子元素的集合。
我最初尝试使用 jackson 来解析 Bean 并生成文件,但我发现该方法在应用于批处理模型时遇到了麻烦。
接下来,我转而对每个子字段使用 StaxEventItemWriter
,这些字段单独看来完全足够,但我在实现可以处理所有各种子类型的编写器时遇到了困难。我研究了 CompositeItemWriter
和 ClassifierCompositeItemWriter
,但它们似乎更适合为同一类型的 bean 提供多个编写器,而我需要适合不同类型的多个编写器。任何建议将不胜感激!
域示例:
public class MyBean {
private RecordBean recordBean;
private List<ChildTypeA> aBeans;
private List<ChildTypeB> bBeans;
private List<ChildTypeC> cBeans;
}
@XmlRootElement(name = "RECORD")
public class RecordBean extends MyAbstractBean {
@XmlElement(name = "ID")
private String recordId;
@XmlElementWrapper(name = "A_CHILDREN")
@XmlElement(name="CHILD_TYPE_A")
List<Long> aChildIds}
@XmlElementWrapper(name = "B_CHILDREN")
@XmlElement(name="CHILD_TYPE_B")
List<Long> bChildIds}
@XmlElementWrapper(name = "C_CHILDREN")
@XmlElement(name="CHILD_TYPE_C")
List<Long> cChildIds}
}
@XmlRootElement(name = "CHILD_TYPE_A")
public class ChildTypeA extends MyAbstractBean {
@XmlElement(name = "ID") private String aId;
}
@XmlRootElement(name = "CHILD_TYPE_B")
public class ChildTypeB extends MyAbstractBean {
@XmlElement(name = "ID") private String bId;
}
@XmlRootElement(name = "CHILD_TYPE_C")
public class ChildTypeC extends MyAbstractBean {
@XmlElement(name = "ID") private String cId;
}
对于传递给编写器的每个容器 bean,我需要为每个 RecordBean
创建一个唯一的 XML 文件,例如record_1.xml,我需要将每个集合写入一个聚合文件,该文件将用作该子类型的所有子项的库,涵盖所有记录。
输出示例: record_1.xml
<?xml version="1.0" encoding="UTF-8"?>
<RECORD>
<ID>1</ID>
<A_CHILDREN>
<CHILD_TYPE_A>1</CHILD_TYPE_A>
<CHILD_TYPE_A>2</CHILD_TYPE_A>
</A_CHILDREN>
<B_CHILDREN>
<CHILD_TYPE_B>1</CHILD_TYPE_B>
<CHILD_TYPE_B>2</CHILD_TYPE_B>
</B_CHILDREN>
<A_CHILDREN>
<CHILD_TYPE_C>1</CHILD_TYPE_C>
<CHILD_TYPE_C>2</CHILD_TYPE_C>
</A_CHILDREN>
</RECORD>
</xml>
record_2.xml
<?xml version="1.0" encoding="UTF-8"?>
<RECORD>
<ID>2</ID>
<A_CHILDREN>
<CHILD_TYPE_A>3</CHILD_TYPE_A>
<CHILD_TYPE_A>4</CHILD_TYPE_A>
</A_CHILDREN>
<B_CHILDREN>
<CHILD_TYPE_B>3</CHILD_TYPE_B>
<CHILD_TYPE_B>4</CHILD_TYPE_B>
</B_CHILDREN>
<A_CHILDREN>
<CHILD_TYPE_C>3</CHILD_TYPE_C>
<CHILD_TYPE_C>4</CHILD_TYPE_C>
</A_CHILDREN>
</RECORD>
</xml>
a_children.xml
<?xml version="1.0" encoding="UTF-8"?>
<A_CHILDREN>
<CHILD_TYPE_A>
<ID>1</ID>
</CHILD_TYPE_A>
<CHILD_TYPE_A>
<ID>2</ID>
</CHILD_TYPE_A>
<CHILD_TYPE_A>
<ID>3</ID>
</CHILD_TYPE_A>
<CHILD_TYPE_A>
<ID>4</ID>
</CHILD_TYPE_A>
</A_CHILDREN>
</xml>
<!-- Decide which format to use -->
b_children.xml 和 c_children.xml 与 a_children.xml 相同。
最佳答案
因此,经过两天的大部分时间,我决定采取不同的方法。我认为可以创建一组编写器来处理该任务,但我认为这需要大量的定制和复杂的委托(delegate)层次结构。
例如:
CompositeItemWriter
委托(delegate)给:ClassifierCompositeItemWriter
进行分类并委托(delegate)给:- ChildTypeA 的
StaxEventItemWriter
StaxEventItemWriter
(适用于 ChildTypeB)StaxEventItemWriter
用于 ChildTypeC
- ChildTypeA 的
MultiResourceItemWriter
为每个 RecordBean 动态分配 FilesystemResource。
尽管事实上这可能是可行的,但我意识到将 XML 写为字符串在任何我想要的地方会更简单。大致如下:
@Component
@Scope("step")
public class MyXmlWriter implements ItemWriter<MyBean> {
@Override
public void write(List<? extends MyBean> beans) throws Exception {
for(MyBean bean : beans) {
this.writeRecordBean(bean.getRecordBean());
bean.getAChildIds().forEach(a -> this.writeElement(a, pathA));
bean.getBChildIds().forEach(b -> this.writeElement(b, pathB));
bean.getCChildIds().forEach(c -> this.writeElement(c, pathC));
}
}
private void writeElement(Long Id, Path path) {
// Handle serialization and FileIO here
}
.
.
.
}
无论如何,我希望这可以帮助任何像我一样深入研究 Spring Batch 杂草的人。干杯!
关于java - 如何在 Spring Batch ItemWriter 中为子 bean 编写多个 XML 文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58545822/