Apache camel - SQL到CSV

问题描述 投票:0回答:3

我试图将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("\r");
                 }
            }
        }

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

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

java xml csv apache-camel blueprint-osgi
3个回答
2
投票

我知道你可以通过一些调整使上面的代码工作,但我想我会提出一个建议,可以让你更容易解决整个问题。 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();

0
投票

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

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("\n");
}
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("\n");
}
System.out.println(csv);

产量

42,Doe,John
Jane,23,Doe

0
投票

我刚刚开始使用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>

© www.soinside.com 2019 - 2024. All rights reserved.