java - 如何在 Spring Batch ItemWriter 中为子 bean 编写多个 XML 文件?
问题描述
我有一个批处理作业,它从数据库中检索记录,处理它们,并将结果传递给编写器。传递给 writer 的 bean 有四个字段需要写入单独的 xml 文件。其中一个字段是代表原始记录的 bean,其他三个字段是与记录关联的子元素的集合。
我最初尝试使用 jackson 来解析 bean 并生成文件,但我发现这种方法在应用于批处理模型时会出现问题。
接下来,我已经转向StaxEventItemWriter
对每个子字段使用 s,这看起来非常合适,但是我在实现一个可以处理所有各种子类型的编写器时遇到了麻烦。我研究了CompositeItemWriter
and 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
例如 record_1.xml 创建一个唯一的 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>
记录_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 相同。
解决方案
所以在两天的大部分时间之后,我决定采取不同的方法。我认为创建一组编写器来处理任务是可能的,但我认为这需要大量的定制和复杂的委托层次结构。
例如:
CompositeItemWriter
代表:ClassifierCompositeItemWriter
分类,并委托给:StaxEventItemWriter
对于 ChildTypeAStaxEventItemWriter
对于 ChildTypeBStaxEventItemWriter
对于 ChildTypeC
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 杂草的人。干杯!
推荐阅读
- html - 修复标题溢出父容器
- node-red - http请求头的全局配置
- c# - Xml 集合的反序列化
- amazon-cloudwatchlogs - 过滤特定字符串并包括以下 2 行
- java - 设备上的 android 应用程序到 PC netbeans java 服务器之间的数据传输
- docker - Dockerfile 未知标志:chown
- java - 如果 MongoDB 关闭并且操作处于挂起状态,应该采取什么策略
- swift - 仅在 collectionViewCell 内的单个对象上刷新或重新加载数据
- sql - 如何在 Python 3.7 中连接到 hadoop/hive 数据库(需要身份验证)并执行简单的 SQL 查询?
- javascript - HTML 图形 - HTML 游戏:共谋控制(破坏和得分)