You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Apache Camel 2.20.0 Mybatis组件使用consumer.useIterator时如何设置查询参数?

好问题!我之前在处理Camel结合MyBatis导出大数据量的场景时,也遇到过这个参数传递的困惑——毕竟MyBatis作为consumer(from端点)时,默认的轮询模式不像生产者(to端点)那样直接支持从Exchange传递参数。下面给你几个实用的解决方案,适配不同的场景:

方案1:使用pollEnrich结合consumer.useExchangeParameters(推荐,动态参数友好)

这个方案适合需要动态参数的场景,通过pollEnrich将参数传递给MyBatis consumer,完美兼容consumer.useIterator的内存优化特性:

  1. 修改路由配置:用触发组件(比如timer)作为入口,设置参数后通过pollEnrich调用MyBatis端点,开启consumer.useExchangeParameters=true让consumer从Exchange Header获取参数:
from("timer:dailyExport?period=86400000") // 每天触发一次,可按需调整周期
    // 动态生成起始日期,比如调用工具类获取昨天的日期
    .setHeader("startDate", method(DateUtils.class, "getYesterdayDate"))
    // 调用MyBatis consumer,开启参数传递开关
    .pollEnrich("mybatis:selectItemsByDate?statementType=SelectList&consumer.useIterator=true&consumer.useExchangeParameters=true")
    // 拆分迭代器中的数据,逐行处理
    .split(body())
    .process(doSomething)
    .to("file:my-path-file");
  1. 配置MyBatis Mapper:确保Mapper接口的方法参数用@Param注解指定参数名,和Camel Header的key完全对应:
public interface ItemMapper {
    List<Item> selectItemsByDate(@Param("startDate") String startDate);
}
  1. 动态参数生成示例:如果需要每次触发的参数不同,比如每天导出前一天的数据,可以写一个简单的工具类:
public class DateUtils {
    public String getYesterdayDate() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DATE, -1);
        return sdf.format(cal.getTime());
    }
}
方案2:使用consumer.parameter指定固定参数(适合参数固定的场景)

如果你的起始日期是固定值,或者可以从系统属性/环境变量获取,直接在端点URI中通过consumer.parameter指定即可:

from("mybatis:selectItemsByDate?statementType=SelectList&consumer.useIterator=true&consumer.parameter=startDate:2024-01-01")
    .split(body())
    .process(doSomething)
    .to("file:my-path-file");

多个参数用逗号分隔,比如consumer.parameter=startDate:2024-01-01,endDate:2024-01-31。

方案3:手动使用PollingConsumer控制参数(适合自定义触发逻辑)

如果需要完全自定义触发时机和参数逻辑,可以手动创建PollingConsumer,在代码中直接设置参数并触发查询:

// 初始化Camel上下文
CamelContext context = new DefaultCamelContext();

// 创建MyBatis端点并初始化PollingConsumer
Endpoint mybatisEndpoint = context.getEndpoint("mybatis:selectItemsByDate?statementType=SelectList&consumer.useIterator=true");
PollingConsumer consumer = mybatisEndpoint.createPollingConsumer();
consumer.start();

// 构造Exchange并设置查询参数
Exchange exchange = consumer.createExchange();
exchange.getIn().setHeader("startDate", "2024-01-01"); // 这里可以动态生成参数

// 触发查询并获取迭代器结果
Exchange resultExchange = consumer.receive(exchange);
Iterator<Item> itemIterator = resultExchange.getIn().getBody(Iterator.class);

// 逐行处理数据
while (itemIterator.hasNext()) {
    Item item = itemIterator.next();
    // 执行自定义处理逻辑
    doSomething.process(new DefaultExchange(context).getIn().setBody(item));
    // 写入文件逻辑...
}

// 关闭资源
consumer.stop();
context.stop();
关键注意事项
  • consumer.useIterator=true会让MyBatis返回Iterator而非List,避免一次性加载大量数据到内存,这正是你需要的内存友好模式。
  • consumer.useExchangeParameters=true是核心配置,开启后MyBatis consumer会从Exchange的In消息Header中读取参数,匹配Mapper中@Param指定的参数名。
  • 如果使用XML配置的MyBatis statement,确保XML中的参数名和Header key一致,比如:
<select id="selectItemsByDate" resultType="com.example.Item">
    SELECT * FROM items WHERE create_time >= #{startDate}
</select>

内容的提问来源于stack exchange,提问作者Oibaf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:38:05