此版本仍在开发中,尚不被认为是稳定的。对于最新的稳定版本,请使用 Spring Integration 6.5.1spring-doc.cadn.net.cn

出站通道适配器

出站通道适配器与入站通道适配器相反:它的作用是处理消息并使用它来执行 SQL 查询。默认情况下,消息有效负载和标头可用作查询的输入参数,如以下示例所示:spring-doc.cadn.net.cn

<int-jdbc:outbound-channel-adapter
    query="insert into items (id, status, name) values (:headers[id], 0, :payload[something])"
    data-source="dataSource"
    channel="input"/>

在前面的示例中,到达标记为input具有键为something,因此运算符会从映射中取消引用该值。标头也作为映射进行访问。[]spring-doc.cadn.net.cn

前面查询中的参数是传入消息上的 bean 属性表达式(而不是 SpEL 表达式)。此行为是SqlParameterSource,这是出站适配器创建的默认源。您可以注入不同的SqlParameterSourceFactory以获得不同的行为。

出站适配器需要对DataSourceJdbcTemplate. 您还可以注入SqlParameterSourceFactory以控制每个传入消息与查询的绑定。要使用SqlParameterSourceFactory(尤其是默认BeanPropertySqlParameterSourceFactory与其MapSqlParameterSource)更流畅,从 6.5 版本开始,JdbcMessageHandler公开一个usePayloadAsParameterSource标志,以指示是否应将整个消息作为参数源输入传递。spring-doc.cadn.net.cn

如果输入通道是直接通道,则出站适配器在与消息发送方相同的线程中运行其查询,因此,如果有,则运行相同的事务(如果有)。spring-doc.cadn.net.cn

使用 SpEL 表达式传递参数

大多数 JDBC 通道适配器的一个常见需求是将参数作为 SQL 查询或存储过程或函数的一部分传递。如前所述,默认情况下,这些参数是 bean 属性表达式,而不是 SpEL 表达式。但是,如果需要将 SpEL 表达式作为参数传递,则必须显式注入SqlParameterSourceFactory.spring-doc.cadn.net.cn

以下示例使用ExpressionEvaluatingSqlParameterSourceFactory要实现该要求:spring-doc.cadn.net.cn

<jdbc:outbound-channel-adapter data-source="dataSource" channel="input"
    query="insert into MESSAGES (MESSAGE_ID,PAYLOAD,CREATED_DATE) values (:id, :payload, :createdDate)"
    sql-parameter-source-factory="spelSource"/>

<bean id="spelSource"
      class="o.s.integration.jdbc.ExpressionEvaluatingSqlParameterSourceFactory">
    <property name="parameterExpressions">
        <map>
            <entry key="id"          value="headers['id'].toString()"/>
            <entry key="createdDate" value="new java.util.Date()"/>
            <entry key="payload"     value="payload"/>
        </map>
    </property>
</bean>

有关详细信息,请参阅定义参数源spring-doc.cadn.net.cn

使用PreparedStatement回调

有时,灵活性和松散耦合SqlParameterSourceFactory没有做我们需要的目标PreparedStatement或者我们需要做一些底层的JDBC工作。Spring JDBC模块提供了配置执行环境的API(如ConnectionCallbackPreparedStatementCreator)并作参数值(例如SqlParameterSource). 它甚至可以访问用于低级作的 API,例如StatementCallback.spring-doc.cadn.net.cn

从 Spring Integration 4.2 开始,MessagePreparedStatementSetter允许在PreparedStatement手动,在requestMessage上下文。 该类的作用与PreparedStatementSetter在标准的 Spring JDBC API 中。实际上,它是直接从内联调用的PreparedStatementSetterJdbcMessageHandler调用executeJdbcTemplate.spring-doc.cadn.net.cn

此功能界面选项与sqlParameterSourceFactory并可用作更强大的替代方案来填充PreparedStatementrequestMessage. 例如,当我们需要存储时,它很有用File数据到数据库BLOB列。以下示例演示了如何执行此作:spring-doc.cadn.net.cn

@Bean
@ServiceActivator(inputChannel = "storeFileChannel")
public MessageHandler jdbcMessageHandler(DataSource dataSource) {
    JdbcMessageHandler jdbcMessageHandler = new JdbcMessageHandler(dataSource,
            "INSERT INTO imagedb (image_name, content, description) VALUES (?, ?, ?)");
    jdbcMessageHandler.setPreparedStatementSetter((ps, m) -> {
        ps.setString(1, m.getHeaders().get(FileHeaders.FILENAME));
        try (FileInputStream inputStream = new FileInputStream((File) m.getPayload())) {
            ps.setBlob(2, inputStream);
        }
        catch (Exception e) {
            throw new MessageHandlingException(m, e);
        }
        ps.setClob(3, new StringReader(m.getHeaders().get("description", String.class)));
    });
    return jdbcMessageHandler;
}

从 XML 配置的角度来看,prepared-statement-setter属性在<int-jdbc:outbound-channel-adapter>元件。 它允许您指定一个MessagePreparedStatementSetterbean 引用。spring-doc.cadn.net.cn

批量更新

从 5.1 版本开始,JdbcMessageHandler执行JdbcOperations.batchUpdate()如果请求消息的有效负载是Iterable实例。 的每个元素Iterable被包装成Message替换为请求消息中的标头,如果此类元素不是Message已经。 在常规的情况下SqlParameterSourceFactory基于配置的这些消息用于构建SqlParameterSource[]对于上述中使用的参数JdbcOperations.batchUpdate()功能。 当MessagePreparedStatementSetter配置,则BatchPreparedStatementSettervariant 用于迭代每个项目的这些消息,并提供的MessagePreparedStatementSetter针对它们调用。当keysGenerated模式已选择。spring-doc.cadn.net.cn