DBLookup Mediator のドキュメントに記載されているように、クエリの最初の行のみが返され、他の結果は無視されました。
複数のレコードを返し、それらを処理するクエリ (SELECT * FROM X) を実行する「最良の方法」があるかどうかを知りたいです。現在、axis2 サービスの実装を行っていますが、wso2 esb によって提供されるメディエーターの組み合わせを使用してその要件を達成する別の方法がありますか??
前もって感謝します。
サンティアゴ。
はい DBlookup メディエーターは複数の行を返しません。2 つの代替手段を使用できます。
1) WSO2 データ サービス サーバーを使用してデータ サービスを作成し、コール アウト メディエーターを使用して ESB からそのサービスを呼び出します。
2)データベースからデータをクエリするクラスメディエーターを作成し、そこからペイロードを作成して、シーケンスを介して送信できます。
別のサービスを作成したり、本格的な WSO2 データ サービス サーバーをセットアップして DB ルックアップ メディエーターの欠点を克服したりするのを避けるために、既存のメディエーターを拡張しましたが、時間の制約から、彼のコードをコミュニティに戻すことはしませんでした。更新された 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;
}
}
DBLookUp メディエーターを使用して複数の行を取得することはできません。ただし、Data Services Server (DSS) を使用してクエリを作成することはできます。次に、call mediator または send mediator を使用してそれらを呼び出すことができます。WSO2 EI では、DSS も利用できます。ドキュメントを参照してください
https://docs.wso2.com/display/EI611/Generating+a+Data+Service https://docs.wso2.com/display/EI611/Exposed+Data+as+a+REST+Resource
ここで、データは REST (DSS リソース内) または SOAP (DSS 操作内) として公開できます。
ここからDBSelectメディエーターを使用するだけですhttps://github.com/ichakios/dbselect-wso2-mediator 使いやすく、JSON結果を返します