正如它在DBLookup Mediator的文档中所述,它只返回查询的第一行,如果它们是其他结果,则被忽略。WSO2 ESB DBLookup中介查询多行
我想知道是否有一个“最好的方式”来运行查询(SELECT * FROM X),返回多个记录,然后处理它们。现在有一天我们正在执行axis2服务,但是还有另一种方式使用由wso2 esb提供的中介组合来实现这个要求?
在此先感谢。
圣地亚哥。
正如它在DBLookup Mediator的文档中所述,它只返回查询的第一行,如果它们是其他结果,则被忽略。WSO2 ESB DBLookup中介查询多行
我想知道是否有一个“最好的方式”来运行查询(SELECT * FROM X),返回多个记录,然后处理它们。现在有一天我们正在执行axis2服务,但是还有另一种方式使用由wso2 esb提供的中介组合来实现这个要求?
在此先感谢。
圣地亚哥。
是DBlookup中介不会返回多行。你可以使用两种选择。
1)使用WSO2 Data services服务器创建数据服务并使用调出中介从ESB调用该服务。
2)您可以编写一个类中介来查询数据库中的数据,然后从中创建一个有效负载,然后通过序列发送它。
为避免编写其他服务或设置完整的WSO2数据服务服务器来克服数据库查找调解器的缺点,我扩展了现有的调解器,但由于时间限制没有将其代码贡献给社区。这里是更新的org.apache.synapse.mediators.db.DBLookupMediator的代码。
基本上,它将ResultSet转换为XML格式并将结果设置为DB_SEARCH_RESULT属性。这可能也需要一些关于比赛条件的抛光和测试。
package org.apache.synapse.mediators.db;
import org.apache.synapse.MessageContext;
import org.apache.synapse.SynapseException;
import org.apache.synapse.SynapseLog;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import java.io.StringWriter;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Connection;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
/**
* Simple database table lookup mediator. Designed only for read/lookup
*/
public class DBLookupMediator extends AbstractDBMediator {
public static final String DB_SEARCH_RESULTS_PROPERTY_NAME = "DB_SEARCH_RESULT";
protected void processStatement(Statement stmnt, MessageContext msgCtx) {
SynapseLog synLog = getLog(msgCtx);
// execute the prepared statement, and extract the first result row and
// set as message context properties, any results that have been specified
Connection con = null;
ResultSet rs = null;
try {
PreparedStatement ps = getPreparedStatement(stmnt, msgCtx);
con = ps.getConnection();
rs = ps.executeQuery();
// convert RS to XML
String rsXML = convertRSToXML(rs);
// add result XML to the Message Context
msgCtx.setProperty(DB_SEARCH_RESULTS_PROPERTY_NAME, rsXML);
// rollback to the beginning of ResultSet to allow standard processing
rs = ps.executeQuery();
if (rs.next()) {
if (synLog.isTraceOrDebugEnabled()) {
synLog.traceOrDebug(
"Processing the first row returned : " + stmnt.getRawStatement());
}
for (String propName : stmnt.getResultsMap().keySet()) {
String columnStr = stmnt.getResultsMap().get(propName);
Object obj;
try {
int colNum = Integer.parseInt(columnStr);
obj = rs.getObject(colNum);
} catch (NumberFormatException ignore) {
obj = rs.getObject(columnStr);
}
if (obj != null) {
if (synLog.isTraceOrDebugEnabled()) {
synLog.traceOrDebug("Column : " + columnStr +
" returned value : " + obj +
" Setting this as the message property : " + propName);
}
msgCtx.setProperty(propName, obj.toString());
} else {
if (synLog.isTraceOrDebugEnabled()) {
synLog.traceOrDebugWarn("Column : " + columnStr +
" returned null Skip setting message property : " + propName);
}
}
}
} else {
if (synLog.isTraceOrDebugEnabled()) {
synLog.traceOrDebug("Statement : "
+ stmnt.getRawStatement() + " returned 0 rows");
}
}
} catch (SQLException e) {
handleException("Error executing statement : " + stmnt.getRawStatement() +
" against DataSource : " + getDSName(), e, msgCtx);
} finally {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {}
}
if (con != null) {
try {
con.close();
} catch (SQLException ignore) {}
}
}
}
private String convertRSToXML(ResultSet rs) throws SQLException {
ResultSetMetaData rsmd = rs.getMetaData();
// create XML document
DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder;
Document doc = null;
try {
docBuilder = dbfac.newDocumentBuilder();
doc = docBuilder.newDocument();
} catch (ParserConfigurationException pce) {
throw new SynapseException("Failed to transform Resultset to XML", pce);
}
// create Root element
Element rootElement = doc.createElement("table");
doc.appendChild(rootElement);
while (rs.next()) {
// add Record element
Element recordElement = doc.createElement("record");
rootElement.appendChild(recordElement);
for (int i = 1; i <= rsmd.getColumnCount(); i++) {
String columnName = rsmd.getColumnName(i);
String columnValue = rs.getObject(i).toString();
// add Field element
Element fieldElement = doc.createElement("field");
fieldElement.appendChild(doc.createTextNode(columnValue));
// set Name attribute to Field element
Attr nameAttr = doc.createAttribute("name");
nameAttr.setValue(columnName);
fieldElement.setAttributeNode(nameAttr);
// add Field to Record
recordElement.appendChild(fieldElement);
}
}
//Output the XML
String xmlString = null;
try {
//set up a transformer
TransformerFactory transfac = TransformerFactory.newInstance();
Transformer trans = transfac.newTransformer();
trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
trans.setOutputProperty(OutputKeys.INDENT, "yes");
//create string from XML tree
StringWriter sw = new StringWriter();
StreamResult result = new StreamResult(sw);
DOMSource source = new DOMSource(doc);
trans.transform(source, result);
xmlString = sw.toString();
} catch (javax.xml.transform.TransformerException te) {
throw new SynapseException("Failed to transform Resultset to XML", te);
}
return xmlString;
}
}
只需从这里https://github.com/ichakios/dbselect-wso2-mediator 容易使用DBSelect中保使用,并返回JSON结果
使用DBLookUp中介不能检索多个行。但是您可以使用数据服务服务器(DSS)并创建查询。然后您可以使用呼叫中介或发送中介来调用它们。在WSO2 EI中,DSS也可用。请参阅文档
https://docs.wso2.com/display/EI611/Generating+a+Data+Service https://docs.wso2.com/display/EI611/Exposing+Data+as+a+REST+Resource
这里的数据可以被暴露为REST(在DSS资源)或SOAP(在DSS操作)。
谢谢谢兰的安抚。我认为这是一个非常普遍的问题,你知道为什么Synapse或WSO2没有提供开箱即用的答案选项2?也许如果消息的有效载荷(查询的结果太大)可能在突触的消息上下文中有一些缺点?或者这没有问题? 再次感谢圣地亚哥。 – smontico 2013-04-28 22:14:08
是的。如果结果集太大,则将它们添加到消息上下文中是一个问题。与此相关的JIRA仍处于开放状态https://issues.apache.org/jira/browse/SYNAPSE-533,因为所提供的解决方案不够优雅。 – 2013-04-28 22:47:21
是的,我明白了,这就是为什么我问你......谢谢谢兰的回应! – smontico 2013-04-29 23:45:37