此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Integration 6.3.1Spring中文文档

此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Integration 6.3.1Spring中文文档

在某些情况下,仅提供简单的 JDBC 支持是不够的。 也许您处理的是遗留的关系数据库架构,或者您有复杂的数据处理需求,但最终,您必须使用存储过程或存储函数。 从 Spring Integration 2.1 开始,我们提供了三个组件来执行存储过程或存储函数:Spring中文文档

支持的数据库

为了启用对存储过程和存储函数的调用,存储过程组件使用 org.springframework.jdbc.core.simple.SimpleJdbcCall 类。 因此,完全支持以下数据库来执行存储过程:Spring中文文档

如果要改为执行存储函数,则完全支持以下数据库:Spring中文文档

即使您的特定数据库可能不完全受支持,只要您的 RDBMS 支持存储过程或存储函数,您仍然可以非常成功地使用存储过程 Spring Integration 组件。Spring中文文档

事实上,一些提供的集成测试使用 H2 数据库。 然而,彻底测试这些使用场景非常重要。Spring中文文档

即使您的特定数据库可能不完全受支持,只要您的 RDBMS 支持存储过程或存储函数,您仍然可以非常成功地使用存储过程 Spring Integration 组件。Spring中文文档

事实上,一些提供的集成测试使用 H2 数据库。 然而,彻底测试这些使用场景非常重要。Spring中文文档

配置

存储过程组件提供完整的 XML 命名空间支持,并且配置这些组件与前面讨论的通用 JDBC 组件类似。Spring中文文档

通用配置属性

所有存储过程组件共享某些配置参数:Spring中文文档

  • auto-startup:生命周期属性指示是否应在应用程序上下文启动期间启动此组件。 它默认为 。 自选。trueSpring中文文档

  • data-source:对用于访问数据库的 的引用。 必填。javax.sql.DataSourceSpring中文文档

  • id:标识基础 Spring Bean 定义,该定义是 或 的实例,具体取决于出站通道适配器的属性引用 a 还是 。 自选。EventDrivenConsumerPollingConsumerchannelSubscribableChannelPollableChannelSpring中文文档

  • ignore-column-meta-data:对于完全受支持的数据库,基础 SimpleJdbcCall 类可以从 JDBC 元数据中自动检索存储过程或存储函数的参数信息。Spring中文文档

    但是,如果数据库不支持元数据查找,或者需要提供自定义参数定义,则可以将此标志设置为 。 它默认为 。 自选。truefalseSpring中文文档

  • is-function:如果 ,则调用 SQL 函数。 在这种情况下,or 属性定义被调用函数的名称。 它默认为 。 自选。truestored-procedure-namestored-procedure-name-expressionfalseSpring中文文档

  • stored-procedure-name:此属性指定存储过程的名称。 如果该属性设置为 ,则此属性将改为指定函数名称。 此属性或必须指定。is-functiontruestored-procedure-name-expressionSpring中文文档

  • stored-procedure-name-expression:此属性使用 SpEL 表达式指定存储过程的名称。 通过使用 SpEL,您可以访问完整的消息(如果可用),包括其标头和有效负载。 可以使用此属性在运行时调用不同的存储过程。 例如,可以提供要作为消息头执行的存储过程名称。 表达式必须解析为 .StringSpring中文文档

    如果该属性设置为 ,则此属性指定存储函数。 此属性或必须指定。is-functiontruestored-procedure-nameSpring中文文档

  • jdbc-call-operations-cache-size:定义缓存实例的最大数量。 基本上,对于每个存储过程名称,都会创建一个新的 SimpleJdbcCallOperations 实例,作为回报,该实例将被缓存。SimpleJdbcCallOperationsSpring中文文档

    Spring Integration 2.2 添加了属性和属性。stored-procedure-name-expressionjdbc-call-operations-cache-size

    默认缓存大小为 。 值为 disables caching。 不允许使用负值。100Spring中文文档

    如果启用 JMX,则有关 的统计信息将作为 MBean 公开。 有关更多信息,请参见 MBean Exporterjdbc-call-operations-cacheSpring中文文档

  • sql-parameter-source-factory:(不适用于存储过程入站通道适配器。 对 . 缺省情况下,传入的有效负载的 Bean 属性通过使用 .SqlParameterSourceFactoryMessageBeanPropertySqlParameterSourceFactorySpring中文文档

    对于基本用例来说,这可能就足够了。 对于更复杂的选项,请考虑传入一个或多个值。 请参阅定义参数源。 自选。ProcedureParameterSpring中文文档

  • use-payload-as-parameter-source:(不适用于存储过程入站通道适配器。 如果设置为 ,则 的有效负载用作提供参数的源。 但是,如果设置为 ,则 whole 可用作参数的源。trueMessagefalseMessageSpring中文文档

    如果未传入任何过程参数,则此属性默认为 。 这意味着,通过使用默认值,有效负载的 Bean 属性将用作存储过程或存储函数的参数值的源。trueBeanPropertySqlParameterSourceFactorySpring中文文档

    但是,如果传入过程参数,则此属性(默认情况下)的计算结果为 。 允许提供 SpEL 表达式。 因此,访问整个 . 在基础 . 上设置的属性。 自选。falseProcedureParameterMessageStoredProcExecutorSpring中文文档

Spring Integration 2.2 添加了属性和属性。stored-procedure-name-expressionjdbc-call-operations-cache-size

通用配置子元素

存储过程组件共享一组通用的子元素,您可以使用这些子元素来定义参数并将其传递给存储过程或存储函数。 可以使用以下元素:Spring中文文档

  • parameterSpring中文文档

  • returning-resultsetSpring中文文档

  • sql-parameter-definitionSpring中文文档

  • pollerSpring中文文档

  • parameter:提供提供存储过程参数的机制。 参数可以是静态的,也可以是使用 SpEL 表达式提供的。Spring中文文档

    <int-jdbc:parameter name=""         (1)
                        type=""         (2)
                        value=""/>      (3)
    
    <int-jdbc:parameter name=""
                        expression=""/> (4)
    1 要传递到存储过程或存储函数的参数的名称。 必填。
    2 此属性指定值的类型。 如果未提供任何内容,则此属性默认为 。 仅当使用该属性时,才使用此属性。 自选。java.lang.Stringvalue
    3 参数的值。 您必须提供此属性或属性。 自选。expression
    4 您可以指定用于传递参数值的 SpEL 表达式,而不是属性。 如果指定 ,则不允许该属性。 自选。 自选。valueexpressionvalue
  • returning-resultset:存储过程可能会返回多个结果集。 通过设置一个或多个元素,可以指定将每个返回的元素转换为有意义的对象。 自选。returning-resultsetRowMappersResultSetSpring中文文档

    <int-jdbc:returning-resultset name="" row-mapper="" />
  • sql-parameter-definition:如果使用完全受支持的数据库,则通常不必指定存储过程参数定义。 相反,这些参数可以自动从 JDBC 元数据派生。 但是,如果使用不完全受支持的数据库,则必须使用元素显式设置这些参数。sql-parameter-definitionSpring中文文档

    您还可以选择使用该属性关闭对通过 JDBC 获取的参数元数据信息的任何处理。ignore-column-meta-dataSpring中文文档

    <int-jdbc:sql-parameter-definition
                                       name=""                           (1)
                                       direction="IN"                    (2)
                                       type="STRING"                     (3)
                                       scale="5"                         (4)
                                       type-name="FOO_STRUCT"            (5)
                                       return-type="fooSqlReturnType"/>  (6)
1 指定 SQL 参数的名称。 必填。
2 指定 SQL 参数定义的方向。 默认值为 。 有效值为:、 和 。 如果过程返回结果集,请使用该元素。 自选。ININOUTINOUTreturning-resultset
3 用于此 SQL 参数定义的 SQL 类型。 转换为整数值,由 定义。 或者,您也可以提供整数值。 如果未显式设置此属性,则默认为“VARCHAR”。 自选。java.sql.Types
4 SQL 参数的刻度。 仅用于数值和十进制参数。 自选。
5 用户命名的 for 类型,例如:、、和命名数组类型。 此属性与属性互斥。 自选。typeNameSTRUCTDISTINCTJAVA_OBJECTscale
6 对复杂类型的自定义值处理程序的引用。 SqlReturnType 的实现。 此属性与该属性互斥,仅适用于 OUT 和 INOUT 参数。 自选。scale
1 要传递到存储过程或存储函数的参数的名称。 必填。
2 此属性指定值的类型。 如果未提供任何内容,则此属性默认为 。 仅当使用该属性时,才使用此属性。 自选。java.lang.Stringvalue
3 参数的值。 您必须提供此属性或属性。 自选。expression
4 您可以指定用于传递参数值的 SpEL 表达式,而不是属性。 如果指定 ,则不允许该属性。 自选。 自选。valueexpressionvalue
1 指定 SQL 参数的名称。 必填。
2 指定 SQL 参数定义的方向。 默认值为 。 有效值为:、 和 。 如果过程返回结果集,请使用该元素。 自选。ININOUTINOUTreturning-resultset
3 用于此 SQL 参数定义的 SQL 类型。 转换为整数值,由 定义。 或者,您也可以提供整数值。 如果未显式设置此属性,则默认为“VARCHAR”。 自选。java.sql.Types
4 SQL 参数的刻度。 仅用于数值和十进制参数。 自选。
5 用户命名的 for 类型,例如:、、和命名数组类型。 此属性与属性互斥。 自选。typeNameSTRUCTDISTINCTJAVA_OBJECTscale
6 对复杂类型的自定义值处理程序的引用。 SqlReturnType 的实现。 此属性与该属性互斥,仅适用于 OUT 和 INOUT 参数。 自选。scale

定义参数源

参数源控制检索 Spring Integration 消息属性并将其映射到相关存储过程输入参数的技术。Spring中文文档

存储过程组件遵循某些规则。 缺省情况下,有效负载的 Bean 属性用作存储过程输入参数的源。 在这种情况下,使用 a。 对于基本用例来说,这可能就足够了。 下一个示例演示了该默认行为。MessageBeanPropertySqlParameterSourceFactorySpring中文文档

要使用 to work 对 Bean 属性进行“自动”查找,Bean 属性必须以小写形式定义。 这是因为在 (Java 方法为 )中,检索到的存储过程参数声明将转换为小写。 因此,如果您具有 camel-case bean 属性(例如 ),则查找将失败。 在这种情况下,请提供显式 .BeanPropertySqlParameterSourceFactoryorg.springframework.jdbc.core.metadata.CallMetaDataContextmatchInParameterValuesWithCallParameters()lastNameProcedureParameter

假设我们有一个有效负载,它由一个具有以下三个属性的简单 Bean 组成:、 和 。 此外,我们有一个简单的存储过程,它接受三个输入参数:、 和 。 我们还使用完全受支持的数据库。 在这种情况下,存储过程出站适配器的以下配置就足够了:idnamedescriptionINSERT_COFFEEidnamedescriptionSpring中文文档

<int-jdbc:stored-proc-outbound-channel-adapter data-source="dataSource"
    channel="insertCoffeeProcedureRequestChannel"
    stored-procedure-name="INSERT_COFFEE"/>

对于更复杂的选项,请考虑传入一个或多个值。ProcedureParameterSpring中文文档

如果显式提供值,则默认情况下,an 用于参数处理,以启用 SpEL 表达式的全部功能。ProcedureParameterExpressionEvaluatingSqlParameterSourceFactorySpring中文文档

如果需要对参数的检索方式进行更多控制,请考虑使用属性传入 by 的自定义实现。SqlParameterSourceFactorysql-parameter-source-factorySpring中文文档

要使用 to work 对 Bean 属性进行“自动”查找,Bean 属性必须以小写形式定义。 这是因为在 (Java 方法为 )中,检索到的存储过程参数声明将转换为小写。 因此,如果您具有 camel-case bean 属性(例如 ),则查找将失败。 在这种情况下,请提供显式 .BeanPropertySqlParameterSourceFactoryorg.springframework.jdbc.core.metadata.CallMetaDataContextmatchInParameterValuesWithCallParameters()lastNameProcedureParameter

存储过程入站通道适配器

以下列表调用了对存储过程入站通道适配器重要的属性:Spring中文文档

<int-jdbc:stored-proc-inbound-channel-adapter
                                   channel=""                                    (1)
                                   stored-procedure-name=""
                                   data-source=""
                                   auto-startup="true"
                                   id=""
                                   ignore-column-meta-data="false"
                                   is-function="false"
                                   skip-undeclared-results=""                    (2)
                                   return-value-required="false"                 (3)
    <int:poller/>
    <int-jdbc:sql-parameter-definition name="" direction="IN"
                                               type="STRING"
                                               scale=""/>
    <int-jdbc:parameter name="" type="" value=""/>
    <int-jdbc:parameter name="" expression=""/>
    <int-jdbc:returning-resultset name="" row-mapper="" />
</int-jdbc:stored-proc-inbound-channel-adapter>
1 轮询消息发送到的通道。 如果存储过程或函数未返回任何数据,则 的有效负载为 null。 必填。Message
2 如果此属性设置为 ,则会绕过存储过程调用中没有相应声明的所有结果。 例如,存储过程可以返回更新计数值,即使存储过程仅声明了一个结果参数。 具体行为取决于数据库实现。 该值在基础 上设置。 该值默认为 。 自选。trueSqlOutParameterJdbcTemplatetrue
3 指示是否应包括此过程的返回值。 自 Spring Integration 3.0 以来。 自选。
1 轮询消息发送到的通道。 如果存储过程或函数未返回任何数据,则 的有效负载为 null。 必填。Message
2 如果此属性设置为 ,则会绕过存储过程调用中没有相应声明的所有结果。 例如,存储过程可以返回更新计数值,即使存储过程仅声明了一个结果参数。 具体行为取决于数据库实现。 该值在基础 上设置。 该值默认为 。 自选。trueSqlOutParameterJdbcTemplatetrue
3 指示是否应包括此过程的返回值。 自 Spring Integration 3.0 以来。 自选。

存储过程出站通道适配器

以下列表调用了对存储过程出站通道适配器重要的属性:Spring中文文档

<int-jdbc:stored-proc-outbound-channel-adapter channel=""                        (1)
                                               stored-procedure-name=""
                                               data-source=""
                                               auto-startup="true"
                                               id=""
                                               ignore-column-meta-data="false"
                                               order=""                          (2)
                                               sql-parameter-source-factory=""
                                               use-payload-as-parameter-source="">
    <int:poller fixed-rate=""/>
    <int-jdbc:sql-parameter-definition name=""/>
    <int-jdbc:parameter name=""/>

</int-jdbc:stored-proc-outbound-channel-adapter>
1 此端点的接收消息通道。 必填。
2 指定此终结点作为订阅者连接到通道时的调用顺序。 当该渠道使用调度策略时,这一点尤其重要。 当此终结点本身是具有队列的通道的轮询使用者时,它不起作用。 自选。failover
1 此端点的接收消息通道。 必填。
2 指定此终结点作为订阅者连接到通道时的调用顺序。 当该渠道使用调度策略时,这一点尤其重要。 当此终结点本身是具有队列的通道的轮询使用者时,它不起作用。 自选。failover

存储过程出站网关

以下列表调用了对存储过程出站通道适配器重要的属性:Spring中文文档

<int-jdbc:stored-proc-outbound-gateway request-channel=""                        (1)
                                       stored-procedure-name=""
                                       data-source=""
                                   auto-startup="true"
                                   id=""
                                   ignore-column-meta-data="false"
                                   is-function="false"
                                   order=""
                                   reply-channel=""                              (2)
                                   reply-timeout=""                              (3)
                                   return-value-required="false"                 (4)
                                   skip-undeclared-results=""                    (5)
                                   sql-parameter-source-factory=""
                                   use-payload-as-parameter-source="">
<int-jdbc:sql-parameter-definition name="" direction="IN"
                                   type=""
                                   scale="10"/>
<int-jdbc:sql-parameter-definition name=""/>
<int-jdbc:parameter name="" type="" value=""/>
<int-jdbc:parameter name="" expression=""/>
<int-jdbc:returning-resultset name="" row-mapper="" />
1 此端点的接收消息通道。 必填。
2 收到数据库响应后应将回复发送到的消息通道。 自选。
3 允许您指定此网关在引发异常之前等待回复消息成功发送的时间。 请记住,当发送到 时,调用发生在发送方的线程中。 因此,发送操作的失败可能是由下游的其他组件引起的。 该值以毫秒为单位指定。 自选。DirectChannel
4 指示是否应包括此过程的返回值。 自选。
5 如果该属性设置为 ,则将绕过存储过程调用中没有相应声明的所有结果。 例如,存储过程可能会返回更新计数值,即使存储过程只声明了一个结果参数。 具体行为取决于数据库。 该值在基础 上设置。 该值默认为 。 自选。skip-undeclared-resultstrueSqlOutParameterJdbcTemplatetrue
1 此端点的接收消息通道。 必填。
2 收到数据库响应后应将回复发送到的消息通道。 自选。
3 允许您指定此网关在引发异常之前等待回复消息成功发送的时间。 请记住,当发送到 时,调用发生在发送方的线程中。 因此,发送操作的失败可能是由下游的其他组件引起的。 该值以毫秒为单位指定。 自选。DirectChannel
4 指示是否应包括此过程的返回值。 自选。
5 如果该属性设置为 ,则将绕过存储过程调用中没有相应声明的所有结果。 例如,存储过程可能会返回更新计数值,即使存储过程只声明了一个结果参数。 具体行为取决于数据库。 该值在基础 上设置。 该值默认为 。 自选。skip-undeclared-resultstrueSqlOutParameterJdbcTemplatetrue

例子

本部分包含两个调用 Apache Derby 存储过程的示例。 第一个过程调用一个存储过程,该存储过程返回 . 通过使用 ,数据被转换为域对象,然后成为 Spring Integration 消息有效负载。ResultSetRowMapperSpring中文文档

在第二个示例中,我们调用一个存储过程,该过程使用输出参数来返回数据。Spring中文文档

该项目包含此处引用的 Apache Derby 示例,以及有关如何运行它的说明。 Spring Integration Samples 项目还提供了使用 Oracle 存储过程的示例Spring中文文档

在第一个示例中,我们调用一个名为 的存储过程,该过程不定义任何输入参数,但返回 .FIND_ALL_COFFEE_BEVERAGESResultSetSpring中文文档

在 Apache Derby 中,存储过程是用 Java 实现的。 以下列表显示了方法签名:Spring中文文档

public static void findAllCoffeeBeverages(ResultSet[] coffeeBeverages)
            throws SQLException {
    ...
}

以下列表显示了相应的 SQL:Spring中文文档

CREATE PROCEDURE FIND_ALL_COFFEE_BEVERAGES() \
PARAMETER STYLE JAVA LANGUAGE JAVA MODIFIES SQL DATA DYNAMIC RESULT SETS 1 \
EXTERNAL NAME 'o.s.i.jdbc.storedproc.derby.DerbyStoredProcedures.findAllCoffeeBeverages';

在 Spring Integration 中,您现在可以使用例如,a 来调用此存储过程,如以下示例所示:stored-proc-outbound-gatewaySpring中文文档

<int-jdbc:stored-proc-outbound-gateway id="outbound-gateway-storedproc-find-all"
                                       data-source="dataSource"
                                       request-channel="findAllProcedureRequestChannel"
                                       expect-single-result="true"
                                       stored-procedure-name="FIND_ALL_COFFEE_BEVERAGES">
<int-jdbc:returning-resultset name="coffeeBeverages"
    row-mapper="org.springframework.integration.support.CoffeBeverageMapper"/>
</int-jdbc:stored-proc-outbound-gateway>

在第二个示例中,我们调用一个名为 that 具有一个输入参数的存储过程。 它不返回 ,而是使用输出参数。 以下示例显示了方法签名:FIND_COFFEEResultSetSpring中文文档

public static void findCoffee(int coffeeId, String[] coffeeDescription)
            throws SQLException {
    ...
}

以下列表显示了相应的 SQL:Spring中文文档

CREATE PROCEDURE FIND_COFFEE(IN ID INTEGER, OUT COFFEE_DESCRIPTION VARCHAR(200)) \
PARAMETER STYLE JAVA LANGUAGE JAVA EXTERNAL NAME \
'org.springframework.integration.jdbc.storedproc.derby.DerbyStoredProcedures.findCoffee';

在 Spring Integration 中,您现在可以通过使用例如,a 来调用此存储过程,如以下示例所示:stored-proc-outbound-gatewaySpring中文文档

<int-jdbc:stored-proc-outbound-gateway id="outbound-gateway-storedproc-find-coffee"
                                       data-source="dataSource"
                                       request-channel="findCoffeeProcedureRequestChannel"
                                       skip-undeclared-results="true"
                                       stored-procedure-name="FIND_COFFEE"
                                       expect-single-result="true">
    <int-jdbc:parameter name="ID" expression="payload" />
</int-jdbc:stored-proc-outbound-gateway>

该项目包含此处引用的 Apache Derby 示例,以及有关如何运行它的说明。 Spring Integration Samples 项目还提供了使用 Oracle 存储过程的示例Spring中文文档