该版本仍在开发中,尚未被视为稳定。对于最新的稳定版本,请使用 Spring Integration 7.0.0spring-doc.cadn.net.cn

存储过程

在某些情况下,单纯的JDBC支持是不够的。也许你处理的是遗留的关系型数据库模式,或者有复杂的数据处理需求,但归根结底,你必须使用存储过程或存储函数。自Spring Integration 2.1以来,我们提供了三个组件来执行存储过程或存储函数:spring-doc.cadn.net.cn

支持的数据库

为了启用对存储过程和存储函数的调用,存储过程组件使用org.springframework.jdbc.core.simple.SimpleJdbcCall类。 因此,以下数据库完全支持用于执行存储过程:spring-doc.cadn.net.cn

如果你想执行存储函数,以下数据库是完全支持的:spring-doc.cadn.net.cn

即使你的数据库可能不完全支持,只要你的关系数据库系统支持存储过程或存储函数,你很可能仍然可以相当成功地使用Spring集成的存储过程组件。spring-doc.cadn.net.cn

事实上,一些提供的集成测试使用H2数据库。 然而,彻底测试这些使用场景非常重要。spring-doc.cadn.net.cn

配置

存储过程组件提供完整的 XML 命名空间支持,组件的配置与之前讨论的通用 JDBC 组件类似。spring-doc.cadn.net.cn

常见配置属性

所有存储过程组件共享某些配置参数:spring-doc.cadn.net.cn

  • 自动启动: 生命周期属性,指示该组件是否应在应用上下文启动时启动。 它默认为true. 自选。spring-doc.cadn.net.cn

  • 数据来源: 指一个javax.sql.数据源,用于访问数据库。 必填。spring-doc.cadn.net.cn

  • 身份证: 表示 Spring Bean 底层定义,即 以下EventDrivenConsumer民调消费者,取决于出站通道适配器是否渠道属性引用 a订阅频道或者Pollable频道. 自选。spring-doc.cadn.net.cn

  • 忽略列元数据对于完全支持的数据库,底层SimpleJdbcCall类可以自动从JDBC元数据中获取存储过程或存储函数的参数信息。spring-doc.cadn.net.cn

    然而,如果数据库不支持元数据查找,或者你需要提供自定义参数定义,则可以将该标志设置为true. 它默认为false. 自选。spring-doc.cadn.net.cn

  • is-函数:如果true调用了一个SQL函数。 在这种情况下,存储过程名称存储过程命名表达式属性定义了被调用函数的名称。 它默认为false. 自选。spring-doc.cadn.net.cn

  • 存储过程名称: 该属性指定存储过程的名称。 如果is-函数属性设置为true,该属性指定函数名称。 要么是这个性质,要么存储过程命名表达式必须说明。spring-doc.cadn.net.cn

  • 存储过程命名表达式: 该属性通过使用 SpEL 表达式指定存储过程的名称。 使用 SpEL 可以访问完整消息(如果有的话),包括其头部和有效载荷。 你可以利用该属性在运行时调用不同的存储过程。 例如,你可以提供想要作为消息头执行的存储过程名称。 该表达式必须解析为字符串.spring-doc.cadn.net.cn

    如果is-函数属性设置为true,该属性指定一个存储函数。 要么是这个性质,要么存储过程名称必须说明。spring-doc.cadn.net.cn

  • jdbc-调用作-缓存大小: 定义了最大缓存数量SimpleJdbcCallOperations实例。 基本上,每个存储过程名称,都有一个新的SimpleJdbcCallOperations创建实例,作为回报,该实例被缓存。spring-doc.cadn.net.cn

    Spring Integration 2.2 增加了存储过程命名表达式属性和jdbc-调用作-缓存大小属性。

    默认缓存大小为10. 一个值为0关闭缓存。 不允许使用负数值。spring-doc.cadn.net.cn

    如果你启用JMX,就能获得关于JDBC-调用作缓存被揭露为MBean。 更多信息请参见MBean出口商spring-doc.cadn.net.cn

  • SQL-参数-源-工厂:(存储过程入站通道适配器不可用。) 对SqlParameterSourceFactory. 默认情况下,传入的豆子属性消息有效载荷作为存储过程输入参数的来源,通过BeanPropertySqlParameterSourceFactory.spring-doc.cadn.net.cn

    这对于基本的使用场景来说可能足够。 对于更复杂的选项,可以考虑通过一个或多个ProcedureParameter值。 参见定义参数来源。 自选。spring-doc.cadn.net.cn

  • 使用有效载荷作为参数源:(存储过程入站通道适配器不可用。) 如果设置为true, 是 的有效载荷消息作为参数的来源。 如果设置为false然而,整个消息作为参数的来源。spring-doc.cadn.net.cn

    如果没有传递过程参数,该属性默认为true. 这意味着,通过使用默认值BeanPropertySqlParameterSourceFactory,有效载荷的豆属性被用作存储过程或存储函数参数值的来源。spring-doc.cadn.net.cn

    然而,如果传递了过程参数,该性质(默认情况下)计算为false.ProcedureParameter允许提供特殊语言表达式。 因此,能够访问全部内容非常有益消息. 标的 的性质集合StoredProcExecutor. 自选。spring-doc.cadn.net.cn

常见配置子元素

存储过程组件共享一组共同的子元素,你可以用这些子元素定义并传递给存储过程或存储函数的参数。 以下元素可用:spring-doc.cadn.net.cn

  • 参数spring-doc.cadn.net.cn

  • 返回结果集spring-doc.cadn.net.cn

  • SQL参数定义spring-doc.cadn.net.cn

  • 轮询者spring-doc.cadn.net.cn

  • 参数:提供一种机制来提供存储过程参数。 参数可以是静态的,也可以通过使用 SpEL 表达式来提供。spring-doc.cadn.net.cn

    <int-jdbc:parameter name=""         (1)
                        type=""         (2)
                        value=""/>      (3)
    
    <int-jdbc:parameter name=""
                        expression=""/> (4)
    1 要传递到存储过程或存储函数的参数名称。 必填。
    2 该属性指定值的类型。 如果没有提供任何信息,该属性默认为java.lang.字符串. 该属性仅在属性被使用。 自选。
    3 参数的值。 您必须提供该属性或表达属性。 自选。
    4 而不是属性,你可以指定一个 SpEL 表达式来传递参数的值。 如果你指定表达不允许属性。 自选。 自选。
  • 返回结果集:存储过程可以返回多个结果集。 通过设置一个或多个返回结果集元素,你可以指定RowMappers 行列图每人回归以转化结果集到有意义的对象。 自选。spring-doc.cadn.net.cn

    <int-jdbc:returning-resultset name="" row-mapper="" />
  • SQL参数定义:如果你使用完全支持的数据库,通常不需要指定存储过程参数定义。 相反,这些参数可以自动从JDBC元数据中推导出来。 然而,如果你使用的数据库未完全支持,你必须通过使用SQL参数定义元素。spring-doc.cadn.net.cn

    你也可以选择关闭通过JDBC获得的参数元数据信息处理,方法是使用忽略列元数据属性。spring-doc.cadn.net.cn

    <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参数定义的方向。 默认. 有效数值如下:,. 如果你的程序返回的是结果集,可以使用返回结果集元素。 自选。
3 用于此SQL参数定义的SQL类型。 转换为整数值,定义为java.sql.类型. 或者,你也可以提供整数值。 如果该属性未被显式设置,则默认为“VARCHAR”。 自选。
4 SQL参数的规模。 仅用于数值和小数参数。 自选。
5 类型名称对于用户命名的类型,例如:结构,不同,JAVA_OBJECT,以及命名的数组类型。 该属性与规模属性。 自选。
6 引用复杂类型的自定义值处理程序。 一个实现SqlReturnType. 该属性与规模属性 和 仅适用于 OUT 和 INOUT 参数。 自选。

参数来源的定义

参数源负责检索和映射 Spring Integration 消息属性到相关存储过程输入参数的技术。spring-doc.cadn.net.cn

存储过程组件遵循一定规则。 默认情况下,豆子的性质消息有效载荷被用作存储过程输入参数的源。 在这种情况下,一个BeanPropertySqlParameterSourceFactory被使用。 这对于基本的使用场景来说可能足够。 下一个例子说明了这种默认行为。spring-doc.cadn.net.cn

对于“自动”查找豆属性,使用BeanPropertySqlParameterSourceFactory要工作,你的豆子属性必须用小写字母定义。 这是因为在org.springframework.jdbc.core.metadata.CallMetaDataContext(Java 方法为matchInParameterValuesWithCallParameters()检索的存储过程参数声明会转换为小写字母。 因此,如果你有骆驼壳豆特性(例如:姓氏),查找失败。 在这种情况下,提供一个明确的ProcedureParameter.

假设我们有一个有效载荷,由一个具有以下三个性质的简单豆子组成:身份证,名称描述. 此外,我们还有一个简单的存储过程,称为INSERT_COFFEE该系统接受三个输入参数:身份证,名称描述. 我们还使用一个完全支持的数据库。 在这种情况下,以下存储过程出站适配器的配置就足够了:spring-doc.cadn.net.cn

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

对于更复杂的选项,可以考虑通过一个或多个ProcedureParameter值。spring-doc.cadn.net.cn

如果你提供ProcedureParameter显式地,默认情况下,一个ExpressionEvaluatingSqlParameterSourceFactory用于参数处理,以实现SpEL表达式的全部功能。spring-doc.cadn.net.cn

如果你还需要更多参数获取的控制,可以考虑传递一个自定义实现SqlParameterSourceFactory通过使用SQL-参数-源-工厂属性。spring-doc.cadn.net.cn

存储过程入信道适配器

以下列表列出了存储过程入站通道适配器的重要属性:spring-doc.cadn.net.cn

<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 轮询消息发送到的信道。 如果存储过程或函数没有返回任何数据,则消息是空。 必填。
2 如果该属性被设置为true,所有存储过程调用的结果都没有对应SqlOutParameter声明被绕过。 例如,存储过程可以返回更新计数值,尽管你的存储过程只声明了一个结果参数。 具体行为取决于数据库的实现方式。 价值是基于标的资产Jdbc模板. 该值默认为true. 自选。
3 表示是否应包含该过程的返回值。 自从春季集成3.0以来, 自选。

存储过程出站通道适配器

以下列表列出了存储过程出站通道适配器的重要属性:spring-doc.cadn.net.cn

<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 指定当该端点作为信道的订阅者连接时的调用顺序。 当该通道使用一个备援切换派遣策略。 当该端点本身是带队列的信道的轮询消费者时,这无效。 自选。

存储过程出站网关

以下列表列出了存储过程出站通道适配器的重要属性:spring-doc.cadn.net.cn

<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 它允许你指定网关在回复消息成功发送前等待多长时间,然后才抛出异常。 请记住,发送给直达频道调用发生在发送方线程中。 因此,发送作失败可能是由下游的其他组件引起的。 该数值以毫秒为单位。 自选。
4 表示是否应包含该过程的返回值。 自选。
5 如果跳过未申报结果属性设置为true,所有存储过程调用的结果都没有对应SqlOutParameter声明被绕过。 例如,存储过程可能会返回更新计数值,尽管你的存储过程只声明了一个结果参数。 具体行为取决于数据库。 价值是基于标的资产Jdbc模板. 该值默认为true. 自选。

例子

本节包含两个调用Apache Derby存储过程的示例。 第一个过程调用一个存储过程,返回结果集. 通过使用行图仪数据被转换为域对象,随后成为 Spring Integration 消息的有效载荷。spring-doc.cadn.net.cn

在第二个示例中,我们调用一个存储过程,使用输出参数返回数据。spring-doc.cadn.net.cn

该项目包含这里提到的Apache Derby示例,以及运行说明。 Spring 集成示例项目也提供了使用 Oracle 存储过程的示例spring-doc.cadn.net.cn

在第一个例子中,我们调用一个名为FIND_ALL_COFFEE_BEVERAGES该参数不定义任何输入参数,但返回结果集.spring-doc.cadn.net.cn

在Apache Derby中,存储过程是用Java实现的。 以下列表展示了方法签名:spring-doc.cadn.net.cn

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

以下列表展示了对应的 SQL:spring-doc.cadn.net.cn

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 中,你现在可以通过使用例如的一个方式调用该存储过程stored-proc-outbound-gateway,如下示例所示:spring-doc.cadn.net.cn

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

在第二个例子中,我们调用一个名为FIND_COFFEE只有一个输入参数。 而不是退回结果集它使用输出参数。 以下示例展示了方法签名:spring-doc.cadn.net.cn

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

以下列表展示了对应的 SQL:spring-doc.cadn.net.cn

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 中,你现在可以通过使用例如的一个方式调用这个存储过程stored-proc-outbound-gateway,如下示例所示:spring-doc.cadn.net.cn

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