Apache camel - SQL到CSV

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Apache camel - SQL到CSV相关的知识,希望对你有一定的参考价值。

我试图将sql结果转换为csv文件,这是路由(blueprint.xml):

<route id="extractfromafbl">
  <from uri="timer:foo?period=10000"/>
  <to uri="sql:select * from performances?dataSource=afbl_source"/>
  <to uri="bean:ngtrend.afbl2afc.transformer?method=tocsv(Exchange)"/>
  <log message="${body}"/>
</route>

这是创建csv格式的变换器类:

    public class transformer {
            public void tocsv(Exchange exchange)
            {
                StringBuilder csv = new StringBuilder();
                List received = exchange.getIn().getBody(List.class);
                for (int i = 0; i < received.size(); i++) 
                 {
                   Map<String,Object> row = (Map<String,Object>) received.get(i);
                   csv.append(row.get("id"));
                   csv.append(",").append(row.get("lastname"));
                   csv.append(",").append(row.get("firstname"));
                   csv.append("
");
                 }
            }
        }

在这种情况下,我应该知道字段的名称(如id,lastname ...),我想使用索引,因为一个或多个表可以更改。

如何使用索引而不是名称字段?

答案

我知道你可以通过一些调整使上面的代码工作,但我想我会提出一个建议,可以让你更容易解决整个问题。 Camel SQL组件允许您自动将数据库响应映射回Object。语法是这样的:

from("sql:select * from performances?dataSource=afbl_source?outputType=SelectList&outputClass=com.myapp.MyDatabaseModel")

一旦你有了这个设置,你将在你的骆驼体中得到一个物体

List<MyDatabaseModel>

此时,您可以利用名为Bindy的驼峰组件。它会让你有一个Object代表一个CSV文件。绑定它的方法是在数据库模型上添加一些注释,这样它也可以表示您的csv输出。

@CsvRecord(isOrdered = true)
public Class MyDatabaseModel{

   @DataField(pos = 1, position = 11)
   private int orderNr;

   @DataField(pos = 2, position = 10)
   private String clientNr;

   ...
}

对Bindy的调用将设置如下:

// Camel 2.15 or older (configure by package name)
BindyCsvDataFormat bindy = new BindyCsvDataFormat("com.myapp");
// Camel 2.16 onwards (configure by class name)
BindyCsvDataFormat bindy = new BindyCsvDataFormat(com.myapp.MyDatabaseModel.class);

.marshal(bindy)

将所有内容整合在一起,您可以将项目分解为2行骆驼和1个java对象来完成此任务。 “下面的全骆驼”

from("sql:select * from performances?dataSource=afbl_source?outputType=SelectList&outputClass=com.myapp.MyDatabaseModel")
    .marshal(bindy);

我想我还应该提一下,如果你不想过多担心csv命令的配置你实际上可以跳过整个注释过程而只是做:

marshal().csv();
另一答案

找一个小片段,表明它不会按你的意愿工作。

List<Map<String, Object>> received = new ArrayList<>();
Map<String, Object> rowOne = new HashMap<>();
rowOne.put("id", 42);
rowOne.put("lastname", "Doe");
rowOne.put("firstname", "John");
Map<String, Object> rowTwo = new HashMap<>();
rowTwo.put("id", 23);
rowTwo.put("lastname", "Doe");
rowTwo.put("firstname", "Jane");
received.add(rowOne);
received.add(rowTwo);
StringBuilder csv = new StringBuilder();
for (Map<String, Object> i : received) {
    StringJoiner line = new StringJoiner(",");
    for (Map.Entry<String, Object> j : i.entrySet()) {
        line.add(j.getValue().toString());
    }
    csv.append(line.toString()).append("
");
}
System.out.println(csv);

产量

John,42,Doe
Jane,23,Doe

值的顺序取决于列的名称和Map的类型。

如果您使用TreeMap,您可能会强制SQL语句返回的列的名称按您要输出的顺序排列(我不建议这样做)

看到这个小片段来展示这个想法

List<Map<String, Object>> received = new ArrayList<>();
Map<String, Object> rowOne = new TreeMap<>();
rowOne.put("1id", 42);
rowOne.put("2lastname", "Doe");
rowOne.put("3firstname", "John");
Map<String, Object> rowTwo = new TreeMap<>();
rowTwo.put("id", 23);
rowTwo.put("lastname", "Doe");
rowTwo.put("firstname", "Jane");
received.add(rowOne);
received.add(rowTwo);
StringBuilder csv = new StringBuilder();
for (Map<String, Object> i : received) {
    StringJoiner line = new StringJoiner(",");
    for (Map.Entry<String, Object> j : i.entrySet()) {
        line.add(j.getValue().toString());
    }
    csv.append(line.toString()).append("
");
}
System.out.println(csv);

产量

42,Doe,John
Jane,23,Doe
另一答案

我刚刚开始使用Camel,所以可能还有另一种方法,但是我可以从表中转储到CSV文件,而不需要知道字段名称:

CsvDataFormat csv = new CsvDataFormat();
csv.setQuoteMode("ALL");

from("sql:select * from MY_TEST_TABLE?dataSource=oracleDataSource&useIterator=false").marshal(csv).to("file:///tmp?fileName=MY_TEST_FILE.csv");

并添加依赖项

    <dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-csv</artifactId>
<version>version</version>

以上是关于Apache camel - SQL到CSV的主要内容,如果未能解决你的问题,请参考以下文章

请让我知道Apache Camel中的民意调查工作机制(CRON JOB)

Apache Camel 2.18中的IN子句

Mark:Camel SQL Route

Apache Camel - Spring 休息端点参考

Apache Camel 和 Intellij Idea 代码格式

Apache Camel http 到 http 路由(有可能吗?)