如何配置JdbcMessageHandler从消息而非静态Bean获取SQL参数
解决方案
问题根因是JdbcMessageHandler默认使用BeanPropertySqlParameterSourceFactory作为参数源工厂,会将JdbcMessageHandler自身实例作为参数查找对象,不会从接收的消息上下文中提取参数。按以下步骤配置即可解决:
1. 配置表达式参数源工厂
引入ExpressionEvaluatingSqlParameterSourceFactory,支持从消息的payload、headers中通过SpEL表达式读取参数:
private MessageHandler cleanupMessageHandler(RuleMetadata rule) { // <原有逻辑省略> SQLTextAndParamsList sql = sqlFactory.getCleanupSQL(rule); JdbcMessageHandler handler = new JdbcMessageHandler(dbprx.getDatasource(), sql.getSql()); // 新增配置:支持从消息上下文提取参数 ExpressionEvaluatingSqlParameterSourceFactory paramFactory = new ExpressionEvaluatingSqlParameterSourceFactory(); // 关闭仅用payload作为参数源的限制,可访问完整消息上下文 paramFactory.setUsePayloadAsParameterSource(false); handler.setSqlParameterSourceFactory(paramFactory); return handler; }
2. SQL参数写法匹配
根据你的参数存储位置选择对应写法:
- 如果参数存储在消息
payload的Map/对象中,直接使用你修改后的SQL写法即可,参数前缀加payload[]: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]) - 如果所有参数都在
payload中,也可以开启usePayloadAsParameterSource简化SQL:
此时SQL可以直接写参数名,无需加paramFactory.setUsePayloadAsParameterSource(true);payload[]前缀: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 = :ID AND (ttobjectname = :ALC_object AND ttschema = :ALC_schema) - 如果参数存储在消息头中,用
:headers[参数名]的写法即可。
内容的提问来源于stack exchange,提问作者pojo-guy
相关产品推荐
相关产品推荐

