我如何配置此 JdbcMessageHandler 以从消息而不是静态 bean 中提取参数?

How do I configure this JdbcMessageHandler to pull parameters from the message instead of static beans?

症状:

调用时,此子流的 cleanupMessageHandler 组件(JdbcMessageHandler)不会从消息中提取参数,而是尝试从静态 bean 中提取参数。

异常信息:

org.springframework.dao.InvalidDataAccessApiUsageException:没有为 SQL 参数提供值 'ALC_startTime':bean class [[=75] 的 属性 'ALC_startTime' 无效=]$1]: Bean 属性 'ALC_startTime' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of getter setter?

SQL

Delete from SB_STREAM.TT_9321383 
WHERE (LASTUPDATESTAMP >= to_timestamp (:ALC_startTime, 'YYYY-MM-DD HH24:MI:SS.FF') 
    and LASTUPDATESTAMP <= to_timestamp (:ALC_endTime, 'YYYY-MM-DD HH24:MI:SS.FF')) 
AND ttkey = BIGINT(:ID) 
AND (ttobjectname = :ALC_object AND ttschema = :ALC_schema)

流量:

   return flowDef
        .filter(getFilterExpression(rule)).channel(new DirectChannel())
        .handle(inboundAdapter) // a JdbcOutboundAdapter
        .split(insertDeleteSplitter)
        .publishSubscribeChannel(taskExecutor, c -> 
                c.subscribe(s -> s
                    .filter ("....")
                    .transform(genericTransformer)
                    .handle(insertUpdateMessageHandler(rule))) // a JDBCMessageHandler
                .subscribe(s -> s
                    .filter("....")
                    .transform(genericTransformer)
                    .handle(deleteMessageHandler(rule))) // a JDBCMessageHandler
                .subscribe(sub -> sub
                    .handle(cleanupMessageHandler(rule))) // a JDBCMessageHandler
              .errorHandler(new CustomErrorHandler() // 
        );

cleanupMessagehandler

private MessageHandler cleanupMessageHandler(RuleMetadata rule) {

<snip ...>
    SQLTextAndParamsList sql = sqlFactory.getCleanupSQL(rule);
    JdbcMessageHandler handler = new JdbcMessageHandler(dbprx.getDatasource(), sql.getSql());

    return handler;
}

JdbcMessageHandler 收到的消息

SQL调用 JDBCOperation 时的 ParameterSources

替代编码 - 调用 JDBCOperation 中值的 batchArray(将 ExpressionEvaluatingSqlParameterSourceFactory 添加到 JdbcMessageHandler)

AbstractNestablePropertyAccessor.getPropertyValue() 处的调试器视图

CachedIntrospectionResults.getPropertyDecriptor() 处的调试器视图


编辑:代码更改

生成的SQL更新为:

Delete from SB_STREAM.TT_9321383 
WHERE (LASTUPDATESTAMP >= to_timestamp (:payload[ALC_startTime], 'YYYY-MM-DD HH24:MI:SS.FF') 
    and LASTUPDATESTAMP <= to_timestamp (:payload[ALC_endTime], 'YYYY-MM-DD HH24:MI:SS.FF')) 
AND ttkey = :payload[ID] 
AND (ttobjectname = :payload[ALC_object] AND ttschema = :payload[ALC_schema])

根据您的第一个屏幕截图,您消息的有效负载是 ArrayList,它确实没有那些 ALC_startTimeALC_endTime 属性。 ArrayList!

上没有那些吸气剂

为了能够阅读列表的内容,您需要在 JdbcMessageHandler 上配置 ExpressionEvaluatingSqlParameterSourceFactory。有关详细信息,请参阅文档:https://docs.spring.io/spring-integration/docs/current/reference/html/jdbc.html#passing-parameters-by-using-spel-expressions.

以某种方式或某种 POJO 表示形式将您的列表转换为 Map 可能更好。使用该列表,您将很难仅通过索引来确定目标值...


编辑: 本次是批量更新,所以地图数组列表是正确的。

SQL 参数中的 SPEl 表达式格式不正确。正确的形式是 :payload[ALC_startTime].