我目前正在从事一个集成项目。我必须从MySQL数据库中获取一些数据,并使用Apache Camel将它们组合起来。在数据库中,我有两个表,分别是materials和packages。它们是一对多关系,一种材料可以包含多个包装。我已经知道如何从数据库中获取数据并将其保存到json文件中,但我不知道如何将这两条消息合并为一条。我读过关于聚合的文章,但我并不真正了解它们。这是我第一次使用Apache Camel,我真的不知道现在该怎么做。这些路由的代码如下所示:
public class InputAdapter{
public static void main(String[] args) throws Exception {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/Packages");
dataSource.setUsername("uname");
dataSource.setPassword("passwd");
SimpleRegistry registry = new SimpleRegistry();
registry.bind("dataSource", dataSource);
CamelContext context = new DefaultCamelContext(registry);
context.addRoutes(new RouteBuilder() {
@Override
public void configure() {
from("timer://foo?repeatCount=1")
.setBody(constant("SELECT * FROM material;"))
.to("jdbc:dataSource")
.marshal().json(true)
.to("file:/some/path/to/file?fileName=materials.json");
from("timer://foo?repeatCount=1")
.setBody(constant("SELECT * FROM package;"))
.to("jdbc:dataSource")
.marshal().json(true)
.to("file:/some/path/to/file?fileName=packages.json");
}
});
context.start();
Thread.sleep(10000);
context.stop();
}
}
材质和包的模型只是具有getter和setter的私有属性:
public class Material {
private int id;
private int number;
private enumType type;
private String name;
private String description;
private boolean is_deleted;
private List<Package> packageList = new ArrayList<>();
public enum enumType {
A1, A2, A3, B1, B2, B3, Z1, Z2, Z3;
}
public int getId() {
return this.id;
}
... some getters
}
public List<Package> getPackageList() {
return this.packageList;
}
public void setId(int id) {
this.id = id;
}
... some setters
public void setPackageList(List<Package> packages) {
this.packageList = packages;
}
}
谁能给我一个提示,我现在该怎么办?请帮帮我。
聚合器通常用于合并来自某个源的消息。我可能不会使用聚合器来组合这两组项目。如果您希望提取所有材质并从数据库中获取关联的包,那么最好检索每个材质的包列表。
我将创建一个处理器来处理检索每个返回材料对象的包,然后在单个路由中输出整个内容。
您可以在Camel中定义一个处理器类,如下所示:
public class PackageProcessor implements Processor {
@Override
public void process(Exchange exchange) {
// Transform the input to your message class
// Retrieve the Packages
// Transform the results to Packages
// Add to the Material
// Set the Out Body
exchange.getMessage().setBody(material);
}
}
然后,您可以使用路由中的处理器来执行此工作。这将使路由看起来像这样:
from("timer://foo?repeatCount=1")
.routeId("my-material-route")
.setBody(constant("SELECT * FROM materials;"))
.to("jdbc:dataSource")
.split(body())
.process(new PackageProcessor())
.setHeader(Exchange.FILE_NAME, simple("${exchangeId}.json"))
.marshal().json(true)
.to("file:/somepath")
.end();
这将把每条记录输出到一个包含所需信息的Json文件中。如果您想将所有项目都放在一个文件中,这就是聚合器发挥作用的地方。
您会注意到路由中的几个项目超出了您的原始路由。JDBC组件的结果是一个ArrayList
处理器完成后,我们将exchange上的CamelFileName头设置为exchange Id,然后这将从Materials表中为每条记录输出一个单独的文件。
如果您想将所有内容都包含在一个文件中,您可以使用聚合器来收集交换并构建列表。让它将交换释放到JSON文件中可能会稍微复杂一点。您通常必须设置超时或某种评估函数来确定何时应该释放“超级”交换。