2013-04-28 57 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; 
    } 

}