使用Mule 3.5加速将DB select转换为XML
我正在尝试将数据从数据库查询转换为XML。大约有两万排。跑步大约需要10分钟,这对我来说太慢了 我注意到eventContext有一个getOutputStream方法,但当我试图调用它时会抛出一个异常,每当我调用它时,它都返回null。我也不具备Java专业知识,不知道流式处理XML的最佳方法,尽管我相信我可以查到这一点,但如果有任何提示,我将不胜感激 我想要的XML的结构类似于:使用Mule 3.5加速将DB select转换为XML,mule,Mule,我正在尝试将数据从数据库查询转换为XML。大约有两万排。跑步大约需要10分钟,这对我来说太慢了 我注意到eventContext有一个getOutputStream方法,但当我试图调用它时会抛出一个异常,每当我调用它时,它都返回null。我也不具备Java专业知识,不知道流式处理XML的最佳方法,尽管我相信我可以查到这一点,但如果有任何提示,我将不胜感激 我想要的XML的结构类似于: <myElements> <myElement> <som
<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
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>
我的骡子流如下所示:
SOME_ID SOME_PROPERTY ANOTHER_ID ANOTHER_PROPERTY
12345 Some Value 67890 Another Value
12345 Some Value 24680 Yet Another Value
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,将DB select设置为streaming=true,但当我这样做时,我在负载中得到的迭代器从hasNext返回false,next抛出一个关于关闭的异常
编辑:更正了调用getOutputStream的结果。问题是,您试图使用dom将一个不合理的大XML加载到内存中,您所经历的10分钟可能大部分时间都花在垃圾收集上,因此要改进这一点,首先要做的是向wrapper.conf添加更多堆,只有当进程在非常低的负载下运行时,才能执行此操作 我建议您尝试一种分而治之的技术,也许可以将您的磁盘用作中间存储 您可以使用stax来流式传输XML
问题是,您正试图使用dom将一个不合理地大到内存中的XML加载到内存中,您所经历的10分钟可能大部分时间都花在垃圾收集上,因此要改进这一点,首先要做的一件小事是向wrapper.conf添加更多堆,只有当该进程在非常低的负载下运行时,您才能这样做 我建议您尝试一种分而治之的技术,也许可以将您的磁盘用作中间存储 您可以使用stax来流式传输XML
谢谢,胡安·阿尔贝托·洛佩斯·卡瓦尔。我试试你的建议。您知道有没有一种方法可以直接流式传输到Mule的输出流,或者我必须在最后写入一个字节数组?或者,您是否建议根本不要使用有效负载机制,告诉Mule从我写入的磁盘加载一个XML文件,并将其放入字节数组?如果您返回一个XML流,然后,mule的xml模块可以负责将其转换为可读的内容,但您可以采取多种方法。谢谢,@Juan Alberto López Cavall。我试试你的建议。您知道有没有一种方法可以直接流式传输到Mule的输出流,或者我必须在最后写入一个字节数组?或者,您是否建议根本不要使用有效负载机制,告诉Mule从我写入的磁盘加载一个XML文件,并将其放入字节数组?如果您返回一个XML流,然后,mule的xml模块可以负责将其转换为可读的内容,但是您可以采取多种方法。