入站通道适配器的主要功能是执行 SQL 查询并将结果集转换为消息。 消息负载是整个结果集(表示为 ),列表中项的类型取决于行映射策略。 默认策略是一个泛型映射器,它为查询结果中的每一行返回一个。 或者,您可以通过添加对实例的引用来更改此设置(有关行映射的更多详细信息,请参阅 Spring JDBC 文档)。SELECTListMapRowMapperSpring中文文档

如果要将查询结果中的行转换为单个消息,可以使用下游拆分器。SELECT

入站适配器还需要对实例或 .JdbcTemplateDataSourceSpring中文文档

除了用于生成消息的语句外,适配器还具有一个语句,该语句将记录标记为已处理,以便它们不会出现在下一个轮询中。 可以通过原始选择的 ID 列表对更新进行参数化。 默认情况下,这是通过命名约定完成的(输入结果集中调用的列将转换为名为 的更新的参数映射中的列表)。 下面的示例定义一个包含更新查询和引用的入站通道适配器。SELECTUPDATEididDataSourceSpring中文文档

<int-jdbc:inbound-channel-adapter query="select * from item where status=2"
    channel="target" data-source="dataSource"
    update="update item set status=10 where id in (:id)" />
更新查询中的参数在参数名称(在前面的示例中是要应用于轮询结果集中的每一行的表达式)的名称中指定冒号 () 前缀。 这是 Spring JDBC 中命名参数 JDBC 支持的标准功能,与 Spring Integration 中采用的约定(投影到轮询结果列表)相结合。 底层的 Spring JDBC 功能限制了可用的表达式(例如,不允许使用句点以外的大多数特殊字符),但由于目标通常是可通过 Bean 路径寻址的对象列表(可能是一个对象列表),因此不会过度限制。:

若要更改参数生成策略,可以将 a 注入适配器以覆盖默认行为(适配器具有属性)。 Spring Integration 提供了 ,它创建了一个基于 SpEL 的参数源,并将查询结果作为对象。 (如果为 true,则根对象为行)。 如果同一参数名称在更新查询中多次出现,则仅计算一次,并缓存其结果。SqlParameterSourceFactorysql-parameter-source-factoryExpressionEvaluatingSqlParameterSourceFactory#rootupdate-per-rowSpring中文文档

还可以将参数源用于选择查询。 在这种情况下,由于没有要计算的“结果”对象,因此每次都使用单个参数源(而不是使用参数源工厂)。 从版本 4.0 开始,您可以使用 Spring 创建基于 SpEL 的参数源,如以下示例所示:Spring中文文档

<int-jdbc:inbound-channel-adapter query="select * from item where status=:status"
	channel="target" data-source="dataSource"
	select-sql-parameter-source="parameterSource" />

<bean id="parameterSource" factory-bean="parameterSourceFactory"
			factory-method="createParameterSourceNoCache">
	<constructor-arg value="" />
</bean>

<bean id="parameterSourceFactory"
		class="o.s.integration.jdbc.ExpressionEvaluatingSqlParameterSourceFactory">
	<property name="parameterExpressions">
		<map>
			<entry key="status" value="@statusBean.which()" />
		</map>
	</property>
</bean>

<bean id="statusBean" class="foo.StatusDetermination" />

每个参数表达式中的 in 可以是任何有效的 SpEL 表达式。 表达式计算的对象是在 Bean 上定义的构造函数参数。 对于所有计算,它都是静态的(在前面的示例中,为空)。value#rootparameterSourceStringSpring中文文档

从 V5.0 开始,您可以提供 with 来指定特定参数的目标 SQL 类型。ExpressionEvaluatingSqlParameterSourceFactorysqlParameterTypesSpring中文文档

以下示例为查询中使用的参数提供 SQL 类型:Spring中文文档

<int-jdbc:inbound-channel-adapter query="select * from item where status=:status"
    channel="target" data-source="dataSource"
    select-sql-parameter-source="parameterSource" />

<bean id="parameterSource" factory-bean="parameterSourceFactory"
            factory-method="createParameterSourceNoCache">
    <constructor-arg value="" />
</bean>

<bean id="parameterSourceFactory"
        class="o.s.integration.jdbc.ExpressionEvaluatingSqlParameterSourceFactory">
    <property name="sqlParameterTypes">
        <map>
            <entry key="status" value="#{ T(java.sql.Types).BINARY}" />
        </map>
    </property>
</bean>
使用工厂方法。 否则,参数源将缓存评估结果。 另请注意,由于禁用了缓存,因此如果相同的参数名称多次出现在选择查询中,则每次出现时都会重新计算该参数名称。createParameterSourceNoCache
如果要将查询结果中的行转换为单个消息,可以使用下游拆分器。SELECT
更新查询中的参数在参数名称(在前面的示例中是要应用于轮询结果集中的每一行的表达式)的名称中指定冒号 () 前缀。 这是 Spring JDBC 中命名参数 JDBC 支持的标准功能,与 Spring Integration 中采用的约定(投影到轮询结果列表)相结合。 底层的 Spring JDBC 功能限制了可用的表达式(例如,不允许使用句点以外的大多数特殊字符),但由于目标通常是可通过 Bean 路径寻址的对象列表(可能是一个对象列表),因此不会过度限制。:
使用工厂方法。 否则,参数源将缓存评估结果。 另请注意,由于禁用了缓存,因此如果相同的参数名称多次出现在选择查询中,则每次出现时都会重新计算该参数名称。createParameterSourceNoCache

轮询和交易

入站适配器接受常规 Spring Integration 轮询器作为子元素。 因此,可以控制轮询的频率(除其他用途外)。 用于 JDBC 的轮询器的一个重要功能是将轮询操作包装在事务中的选项,如以下示例所示:Spring中文文档

<int-jdbc:inbound-channel-adapter query="..."
        channel="target" data-source="dataSource" update="...">
    <int:poller fixed-rate="1000">
        <int:transactional/>
    </int:poller>
</int-jdbc:inbound-channel-adapter>
如果未显式指定轮询器,则使用默认值。 与 Spring Integration 一样,它可以定义为顶级 bean)。

在前面的示例中,数据库每 1000 毫秒(或每秒轮询一次)进行一次轮询,并且 update 和 select 查询都在同一事务中执行。 不显示事务管理器配置。 但是,只要它知道数据源,轮询就是事务性的。 一个常见的用例是将下游通道设置为直接通道(默认),以便在同一线程中调用端点,从而调用相同的事务。 这样,如果其中任何一个失败,事务将回滚,输入数据将恢复到其原始状态。Spring中文文档

如果未显式指定轮询器,则使用默认值。 与 Spring Integration 一样,它可以定义为顶级 bean)。

max-rowsmax-messages-per-poll

JDBC 入站通道适配器定义了一个名为 的属性。 指定适配器的轮询程序时,还可以定义名为 的属性。 虽然这两个属性看起来很相似,但它们的含义却大不相同。max-rowsmax-messages-per-pollSpring中文文档

max-messages-per-poll指定每个轮询间隔执行查询的次数,而指定每次执行返回的行数。max-rowsSpring中文文档

在正常情况下,您可能不希望在使用 JDBC 入站通道适配器时设置轮询器的属性。 其缺省值为 ,这意味着 JDBC 入站通道适配器的 receive() 方法在每个轮询间隔内只执行一次。max-messages-per-poll1Spring中文文档

将属性设置为更大的值意味着查询将连续执行多次。 有关该属性的详细信息,请参阅配置入站通道适配器max-messages-per-pollmax-messages-per-pollSpring中文文档

相反,如果该属性大于 ,则指定该方法创建的查询结果集中要使用的最大行数。 如果该属性设置为 ,则所有行都包含在生成的消息中。 该属性默认为 。max-rows0receive()00Spring中文文档

建议通过特定于供应商的查询选项(例如 MySQL 或 SQL Server 或 Oracle 的 . 有关详细信息,请参阅特定的供应商文档。LIMITTOPROWNUM
建议通过特定于供应商的查询选项(例如 MySQL 或 SQL Server 或 Oracle 的 . 有关详细信息,请参阅特定的供应商文档。LIMITTOPROWNUM