带有 SQL 组件的 Apache Camel 用于使用 batch=true 插入的多个表会引发错误

问题描述

我正在使用带有 sql 组件的 Apache camel 来使用 Postgresql 执行 sql 操作。我已经尝试使用 batch=true 选项在单个表中成功插入多行,并在消息正文中提供迭代器。为了使示例简单,Student 作为表名并有 2 列 nameage,下面是显示相关部分的代码片段:

from("direct:batch_insert_single_table")
...
.process(ex -> {
    log.info("batch insert for single table");
    final var iterator = IntStream.range(0,5000).Boxed()
            .map(x -> {
                final var query = new HashMap<String,Object>();
                Integer counter = x.intValue();
                String name = "abc_" + counter;
                query.put("name",name);
                query.put("age",counter);               
                return query;
            }).iterator();
    ex.getMessage().setBody(iterator);
})
.to("sqlComponent:INSERT INTO student (name,age) VALUES (:#name,:#age);?batch=true")
...
;

5000 条记录总共需要 10 秒。

但是,当我使用相同的方法多个不同的表上批量插入时,出现错误

这是不起作用的代码

from("direct:batch_insert_multiple_tables")
...
.process(ex -> {
    log.info("batch insert for multiple tables");
    final var iterator = IntStream.range(0,3).Boxed()
            .map(x -> {
                final var query = new HashMap<String,Object>();
                Integer counter = x.intValue();
                String name = "abc_" + counter;
                query.put("table","test" + counter);
                query.put("name","name");
                query.put("age",counter);               
                return query;
            }).iterator();
    ex.getMessage().setBody(iterator);
})
.to("sqlComponent:INSERT INTO :#table (name,:#age);?batch=true")
...
;

表 test0、test1 和 test2 已经存在。 抛出的异常是:

Failed delivery for (MessageId: A0D98C12BAD769F-0000000000000000 on ExchangeId: A0D98C12BAD769F-0000000000000000). Exhausted after delivery attempt: 1 caught: org.springframework.jdbc.BadsqlGrammarException: PreparedStatementCallback; bad sql grammar []; nested exception is org.postgresql.util.PsqlException: ERROR: Syntax error at or near "$1"
Position: 13

如果我做错了什么,或者 Apache Camel 根本不支持我的方法,请提出建议。

注意:我使用的是最新版本的 apache camel 和 Postgre。

问候, GSN

解决方法

您不能在 PostgreSQL 中为表名、列名或任何其他标识符使用参数。您必须使用动态生成的 SQL 语句(即,您在 Java 代码中构造的语句;特别注意 SQL 注入)或两个 SQL 语句。