'int-jdbc:stored-proc-outbound-gateway'能够自己映射你的模型元素 - 这是一个真正的陈述吗?

时间:2014-11-07 16:41:01

标签: spring-integration

目前我正在使用JDBC Spring Integration(非常具体:<int-jdbc:stored-proc-outbound-gateway>),其中场景将n个参数传递给存储过程(ORACLE)并接收一个返回变量(使用&#39 ; 1&#39;或错误消息)以及可能有n列数的n个CURSORS(sys_refcursor)。

在使用Spring Framework处理上述场景时,我注意到以下问题:

我的前端逻辑是,首先阅读&#39;返回变量&#39;。如果该值为1,则通过将用户重定向到错误页面来开始读取所有CURSORS数据或通过异常。现在,我所有的CURSORS都没有相同数量的列以及相同的长度/类型的数据。在中间层我只有一个Model类来处理所有CURSORS返回元素。这对我来说是一个挑战!

以前我只处理过一个CURSOR。因此在中间层我使用Mapper类将所有CURSOR元素映射到我的Model元素(getter和setter)以将数据推送到前面。但是当使用相同的概念来处理n个CURSORS时 - 这真的是一场噩梦。

让我分享一下我之前做过的事情,以及我后来为了解决这种情况而做出的事情,然后我会在本文的后半部分提出我的理解,这将使得EXPARTS的意见不足。

对于一个返回变量(带有&#39; 1&#39;或错误消息)以及一个CURSOR : 我的网关定义如下:

<!-- Stored Procedure Outbound-Gateway = To call a database stored procedure -->        
<int-jdbc:stored-proc-outbound-gateway  id="outbound-gateway-storedproc-personalinfo"
                                            request-channel="procedureRequestChannel"
                                            data-source="dataSource"
                                            stored-procedure-name="pkg_personalinfo_spring.proc_personalinfo_spring"
                                            expect-single-result="false"
                                            ignore-column-meta-data="true">
        <!-- Parameter Definitions -->                                      
        <int-jdbc:sql-parameter-definition  name="firstname" direction="IN"/>
        <int-jdbc:sql-parameter-definition  name="lastname" direction="IN"/>
        <int-jdbc:sql-parameter-definition name="p_RetVal" direction="OUT"/>
        <int-jdbc:sql-parameter-definition name="get_ResultSet" type="#{T(oracle.jdbc.OracleTypes).CURSOR}" direction="OUT"/>

        <!-- Parameter Mappings Before Passing & Receiving -->                              
        <int-jdbc:parameter name="firstname" expression="payload[0]"/>
        <int-jdbc:parameter name="lastname" expression="payload[1]"/>
        <int-jdbc:returning-resultset name="get_ResultSet" row-mapper="com.support.PersonalinfoMapper"/>

</int-jdbc:stored-proc-outbound-gateway>

在Mapper类中,我有以下简单的映射规则:

...
PersonalInfo personalInfo = new PersonalInfo();

        try{
            personalInfo.setFirstname(resultSet.getString(DBConstants.FIRSTNAME));
            personalInfo.setLastname(resultSet.getString(DBConstants.LASTNAME));
... 

我这样做是因为在我的Model类中,我有所有CURSOR返回元素的getter和setter。

现在,对于一个返回变量(带有&#39; 1&#39;或错误消息)以及 n个CURSORS : 我更改了我的网关定义如下:

<!-- Stored Procedure Outbound-Gateway = To call a database stored procedure -->  
<int-jdbc:stored-proc-outbound-gateway  id="outbound-gateway-storedproc-personalinfo"
                                            request-channel="procedureRequestChannel"
                                            data-source="dataSource"
                                            stored-procedure-name="pkg_personalinfo_spring.proc_personalinfo_spring"
                                            expect-single-result="false"
                                            ignore-column-meta-data="true">
        <!-- Parameter Definitions -->                                      
        <int-jdbc:sql-parameter-definition  name="firstname" direction="IN"/>
        <int-jdbc:sql-parameter-definition  name="lastname" direction="IN"/>
        <int-jdbc:sql-parameter-definition name="p_RetVal" direction="OUT"/>
        <int-jdbc:sql-parameter-definition name="get_curr_1" type="#{T(oracle.jdbc.OracleTypes).CURSOR}" direction="OUT"/>
        <int-jdbc:sql-parameter-definition name="get_curr_2" type="#{T(oracle.jdbc.OracleTypes).CURSOR}" direction="OUT"/>

        <!-- Parameter Mappings Before Passing & Receiving -->                              
        <int-jdbc:parameter name="firstname" expression="payload[0]"/>
        <int-jdbc:parameter name="lastname" expression="payload[1]"/>

</int-jdbc:stored-proc-outbound-gateway>

其次我删除了整个行映射概念,意味着我没有任何Mapper类。我唯一拥有的只有一个Model类,包含所有CURSORS元素名称及其getter和setter。

另请注意,在我的“参数定义”中,如何添加这两个CURSORS定义,但在“传递前的参数映射”和“接收&#39;我现在什么也没有。

我没有任何例外地运行应用程序,后来通过Fiddler观察到RESPOND附带的以下JSON数据,意味着一切都完美! ;)

JSON
  - {}
     -  get_curr_1
     -   -{}
     -     -    firstname=Faisal
     -     -    lastname=Quazi
     -  get_curr_2
     -   -{}
     -     -    country=Bangladesh
     -     -    capital=Dhaka

什么是黑客?是的......我有同样的感受;)

现在,任何人都可以帮助理解这里发生了什么。这是一个真实的陈述&#34;&#39; int-jdbc:stored-proc-outbound-gateway&#39;能够神奇地映射你的模型元素???&#34;

有没有最好的做法来处理这种情况?

总是谢谢你们:)

1 个答案:

答案 0 :(得分:1)

:-)。我想默认情况下Spring JDBC使用ColumnMapRowMapper

所以你最终会在Map<String, <Map<?, ?>>>之类的网关之后结束。但无论如何它都是Map

由于您进一步将payload转换为JSON,杰克逊可以完美地处理地图,因此您可以获得正确的结果。

我当然可以debug,但扣除说它可以有所不同。

<强>更新

正如我所说。答案在JdbcTemplate#extractOutputParameters

....
if (outParam.isResultSetSupported()) {                                                     
    returnedResults.putAll(processResultSet((ResultSet) out, outParam));                   
}                                                                                          
else {                                                                                     
    String rsName = outParam.getName();                                                    
    SqlReturnResultSet rsParam = new SqlReturnResultSet(rsName, new ColumnMapRowMapper()); 
    returnedResults.putAll(processResultSet((ResultSet) out, rsParam));                    
    if (logger.isDebugEnabled()) {                                                         
        logger.debug("Added default SqlReturnResultSet parameter named '" + rsName + "'"); 
    }                                                                                      
}                                                                                          
....