我正在尝试将数据从数据库查询转换为XML。大约有20,000行。运行需要十分钟,这对我来说似乎过于缓慢。
我注意到eventContext
有一个getOutputStream
方法,但是当我尝试调用它时会抛出异常每当我调用它时都会返回null。我也没有Java专业知识来了解流式传输XML的最佳方式,虽然我确信我可以查看它,但我很感激其中的任何提示。
我想要的XML结构如下:
<myElements>
<myElement>
<someId>123454</someId>
<someProperty>Some Value</someProperty>
<mySubElements>
<mySubElement>
<anotherId>67890</anotherId>
<anotherProperty>Another Value</anotherProperty>
</mySubElement>
<mySubElement>
<anotherId>24680</anotherId>
<anotherProperty>Yet Another Value</anotherProperty>
</mySubElement>
</mySubElements>
</myElement>
</myElements>
我的查询输出是这样的:
SOME_ID SOME_PROPERTY ANOTHER_ID ANOTHER_PROPERTY
12345 Some Value 67890 Another Value
12345 Some Value 24680 Yet Another Value
我正在使用component
转换器,我的代码看起来像这样:
public Object onCall(MuleEventContext eventContext) throws Exception {
List queryResults = (List) eventContext.getMessage().getPayload();
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
// root elements
Document doc = docBuilder.newDocument();
Element myElements = doc.createElement("myElements");
doc.appendChild(myElements);
Element myElement = null;
Integer currentSomeId = null;
for (Integer i = 0; i < queryResults.size(); i++)
{
Map queryRow = (Map) queryResults.get(i);
if (!queryRow.get("SOME_ID").equals(currentSomeId))
{
myElement = doc.createElement("myElement");
/* populate my element, including with an empty mySubElements */
}
Element mySubElement = doc.createElement("myElement");
/* populate mySubElement */
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
TransformerFactory tf = TransformerFactory.newInstance();
Transformer t = tf.newTransformer();
t.setOutputProperty(OutputKeys.INDENT, "yes");
t.transform(new DOMSource(doc), new StreamResult(baos));
eventContext.getMessage().setPayload(doc);
return baos.toByteArray();
}
我的骡子流看起来像这样:
<flow name="MyElementsFlow-Https">
<http:listener config-ref="HTTP_Listener_Configuration" path="${webapi.myelements.path}" allowedMethods="GET" doc:name="HTTP"/>
<flow-ref name="MyElementsFlow" doc:name="Flow Reference"/>
</flow>
<flow name="MyElementsFlow" processingStrategy="synchronous">
<db:select config-ref="DB-Connector" doc:name="Select">
<db:template-query-ref name="select-template" />
</db:select>
<component class="myJavaComponent" doc:name="To XML"/>
</flow>
编辑:我以为我会尝试将HTTP连接器设置为responseStreamingMode="ALWAYS"
而数据库选择streaming="true"
,但是当我这样做时,我进入的迭代器我的有效负载从false
返回hasNext()
,而next()
会抛出关闭的异常。
修改:更正了调用getOutputStream
的结果。
答案 0 :(得分:0)
问题是你正在尝试加载一个对内存来说不合理的XML(通过使用dom),你遇到的10分钟可能花费在垃圾收集中,所以最重要的是要做的事情。改进这是为了向wrapper.conf添加更多堆,只有当进程在非常低的负载下运行时才能这样做。
我建议您尝试分而治之的技巧,也许可以将您的磁盘用作中间存储。
您可以使用stax来传输XML
https://docs.oracle.com/javase/tutorial/jaxp/stax/using.html