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)