出站通道适配器是入站通道适配器的反面:它的作用是处理消息并使用它来执行 SQL 查询。 默认情况下,消息有效负载和标头可用作查询的输入参数,如下例所示:
<int-jdbc:outbound-channel-adapter
query="insert into items (id, status, name) values (:headers[id], 0, :payload[something])"
data-source="dataSource"
channel="input"/>
在前面的示例中,到达标记为的通道的消息具有 map 的有效负载,其键为 ,因此运算符从 map 中取消引用该值。
标头也作为映射进行访问。input
something
[]
上述查询中的参数是传入消息上的 Bean 属性表达式(不是 SPEL 表达式)。
此行为是 的一部分,它是出站适配器创建的默认源。
你可以注入不同的 API 来获得不同的行为。SqlParameterSource SqlParameterSourceFactory |
出站适配器需要对 a 或 a 的引用。
您还可以注入 a 来控制每个传入消息与查询的绑定。DataSource
JdbcTemplate
SqlParameterSourceFactory
如果 input 通道是直接通道,则出站适配器在与消息发送方相同的线程中运行其查询,因此,与消息的发送者相同的事务(如果有的话)。
上述查询中的参数是传入消息上的 Bean 属性表达式(不是 SPEL 表达式)。
此行为是 的一部分,它是出站适配器创建的默认源。
你可以注入不同的 API 来获得不同的行为。SqlParameterSource SqlParameterSourceFactory |
使用 SPEL 表达式传递参数
大多数 JDBC 通道适配器的常见要求是将参数作为 SQL 查询或存储过程或函数的一部分进行传递。
如前所述,默认情况下,这些参数是 Bean 属性表达式,而不是 SPEL 表达式。
但是,如果需要将 SpEL 表达式作为参数传递,则必须显式注入 .SqlParameterSourceFactory
下面的示例使用 a 来实现该要求:ExpressionEvaluatingSqlParameterSourceFactory
<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>
有关详细信息,请参阅 定义参数源。
使用回调PreparedStatement
有时,的灵活性和松散耦合并不能完成我们对目标的需求,或者我们需要做一些低级的 JDBC 工作。
Spring JDBC 模块提供了 API 来配置执行环境(如 或 )和操作参数值(如 )。
它甚至可以访问用于低级操作的 API,例如 .SqlParameterSourceFactory
PreparedStatement
ConnectionCallback
PreparedStatementCreator
SqlParameterSource
StatementCallback
从 Spring Integration 4.2 开始,允许在上下文中手动指定参数。
这个类的作用与标准 Spring JDBC API 中的角色完全相同。
实际上,当对 .MessagePreparedStatementSetter
PreparedStatement
requestMessage
PreparedStatementSetter
PreparedStatementSetter
JdbcMessageHandler
execute
JdbcTemplate
此功能接口选项与 互斥,可以用作更强大的替代方法,用于填充 的参数。
例如,当我们需要以流式处理方式将数据存储到 DataBase 列时,它非常有用。
以下示例显示了如何执行此操作:sqlParameterSourceFactory
PreparedStatement
requestMessage
File
BLOB
@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 配置的角度来看,该属性在组件上可用。
它允许您指定 Bean 引用。prepared-statement-setter
<int-jdbc:outbound-channel-adapter>
MessagePreparedStatementSetter
批量更新
从版本 5.1 开始,如果请求消息的有效负载是实例,则执行 。
如果 this 元素不是 ,则 the 的每个元素都与请求消息中的 Headers 一起包装到 a。
在基于 regular 的配置的情况下,这些消息用于构建上述函数中使用的 for 参数。
应用配置后,将使用 variant 遍历每个项目的这些消息,并针对它们调用 provided 。
选择模式时,不支持批量更新。JdbcMessageHandler
JdbcOperations.batchUpdate()
Iterable
Iterable
Message
Message
SqlParameterSourceFactory
SqlParameterSource[]
JdbcOperations.batchUpdate()
MessagePreparedStatementSetter
BatchPreparedStatementSetter
MessagePreparedStatementSetter
keysGenerated