2013-04-28 109 views
6

正如它在DBLookup Mediator的文檔中所述,它只返回查詢的第一行,如果它們是其他結果,則被忽略。WSO2 ESB DBLookup中介查詢多行

我想知道是否有一個「最好的方式」來運行查詢(SELECT * FROM X),返回多個記錄,然後處理它們。現在有一天我們正在執行axis2服務,但是還有另一種方式使用由wso2 esb提供的中介組合來實現這個要求?

在此先感謝。

聖地亞哥。

回答

6

是DBlookup中介不會返回多行。你可以使用兩種選擇。

1)使用WSO2 Data services服務器創建數據服務並使用調出中介從ESB調用該服務。

2)您可以編寫一個類中介來查詢數據庫中的數據,然後從中創建一個有效負載,然後通過序列發送它。

+1

謝謝謝蘭的安撫。我認爲這是一個非常普遍的問題,你知道爲什麼Synapse或WSO2沒有提供開箱即用的答案選項2?也許如果消息的有效載荷(查詢的結果太大)可能在突觸的消息上下文中有一些缺點?或者這沒有問題? 再次感謝聖地亞哥。 – smontico 2013-04-28 22:14:08

+0

是的。如果結果集太大,則將它們添加到消息上下文中是一個問題。與此相關的JIRA仍處於開放狀態https://issues.apache.org/jira/browse/SYNAPSE-533,因爲所提供的解決方案不夠優雅。 – 2013-04-28 22:47:21

+0

是的,我明白了,這就是爲什麼我問你......謝謝謝蘭的迴應! – smontico 2013-04-29 23:45:37

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; 
    } 

}