出站通道适配器

出站通道适配器是入站通道适配器的反面:它的作用是处理消息并使用它来执行 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具有 Key 为something,因此运算符会从 map 中取消引用该值。 标头也作为映射进行访问。[]spring-doc.cadn.net.cn

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

出站适配器需要引用DataSourceJdbcTemplate. 您还可以注入SqlParameterSourceFactory控制每个传入消息与查询的绑定。spring-doc.cadn.net.cn

如果 input 通道是直接通道,则出站适配器在与消息发送方相同的线程中运行其查询,因此,与消息的发送者相同的事务(如果有的话)。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允许在PreparedStatementmanually,在requestMessage上下文。 该类的作用与PreparedStatementSetter在标准 Spring JDBC API 中。 实际上,它是直接从内联PreparedStatementSetterimplementation 时,JdbcMessageHandler调用executeJdbcTemplate.spring-doc.cadn.net.cn

此功能接口选项与sqlParameterSourceFactory,并且可以用作更强大的替代方案来填充PreparedStatementrequestMessage. 例如,当我们需要存储Filedata 到 DataBaseBLOB列。 以下示例显示了如何执行此作: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