Apache Cayenne:将固定与动态提供的 DataMap 合并到一个 ServerRuntime
Posted
技术标签:
【中文标题】Apache Cayenne:将固定与动态提供的 DataMap 合并到一个 ServerRuntime【英文标题】:Apache Cayenne: Merging fixed with dynamically supplied DataMaps into one ServerRuntime 【发布时间】:2018-07-16 13:08:56 【问题描述】:我的应用程序设计包含固定和动态 DataMap 以连接到不同的 (Oracle) 数据库实例/用户。为简单起见,我确实将它们分成了两个不同的 Cayenne 项目。
-
使用固定的 DataMap 创建 ServerRuntimeBuilder,构建和查询我的客户表。
对于每个客户,使用第二个 ServerRuntimeBuilder 加载动态 DataMap,并进行必要的修改(更改名称和默认模式):
...
List<Customer> allCustomers = Customer.allCustomers(this.cayenneRuntime1.newContext());
for (Customer customer : allCustomers)
final String dbPrefix = customer.getDbprefix();
ServerRuntimeBuilder builder = ServerRuntime.builder();
// load and modify DataMap
builder.addConfig("ApacheCayenne/Data/cayenne-dynamicDomain.xml");
builder.addModule(binder ->
binder.bind(DataMapLoader.class).to(MyDataMapLoader.class);
ServerModule.contributeProperties(binder).put("CUSTOMER_PREFIX", dbPrefix);
);
ServerRuntime cayenneRuntime2 = builder.build();
LOG.info("Initialized customer model " + customer + " prefix: " + customer.getDbprefix());
// TODO Merge with cayenneRuntime1?
public class MyDataMapLoader extends XMLDataMapLoader
@Inject
private RuntimeProperties properties;
@Override
public DataMap load(Resource configurationResource) throws CayenneRuntimeException
DataMap map = super.load(configurationResource);
// Dynamically set name and default schema to map
String dbPrefix = properties.get("CUSTOMER_PREFIX");
map.setName(customer1.dbPrefix + "...")
map.setDefaultSchema(customer1.dbPrefix + "...")
return map;
另外还有一个自己的 ConfiguredDataSource 实现,它负责 JDBC 连接 URL 和凭据。到目前为止,这部分工作正常。
我的问题:通过这种设计,我最终为每个客户提供了 1 + n 个 ServerRuntimes。但最后我想要一个单一的ServerRuntime。
a) 是否可以将这些 ServerRuntime 与 Cayenne 4.0RC1 功能和未来版本即时合并?
b) 我是否需要在cayenne-project 库的帮助下阅读动态地图,如here 所述。修改每个动态项目并将其存储到文件系统。在处理完我的所有客户后,使用所描述的方式使用 ExecutingMergerContext 或 Merging Multiple Projects?
创建一个包含所有 Cayenne 项目的最终 ServerRuntimeServerRuntime runtime = ServerRuntime.builder()
.addConfig("com/example/cayenne-fixed-project.xml")
.addConfig("org/foo/cayenne-dynamic-Customer1.xml")
.addConfig("org/foo/cayenne-dynamic-Customer2.xml")
.build();
提前感谢您帮助我。
【问题讨论】:
【参考方案1】:我会启动 runtime1 以获取配置数据,然后创建包含固定和动态映射的 runtime2,以及用于动态重写名称和架构的自定义 DataMap 加载器:
ServerRuntime runtime2 = ServerRuntime.builder()
.addConfig("com/example/cayenne-fixed-project.xml")
.addConfig("org/foo/cayenne-dynamic-Customer1.xml")
.addConfig("org/foo/cayenne-dynamic-Customer2.xml")
.addModule(..)
.build();
当你完成时不要忘记关闭 runtime1,这样你最后只会有一个运行时。
【讨论】:
非常感谢。使用 Modules 和 DI 为动态 DataMap(它们相应的 DataNodeConfig)正确设置连接凭据有点棘手。 binder.bind(DataChannelDescriptorLoader.class).to(MyDataDomainProvider.class); binder.bind(DataMapLoader.class).to(MyDataMapLoader.class);并注入一个自己的 ConfigurationInfo 持有者实例,对我有用。以上是关于Apache Cayenne:将固定与动态提供的 DataMap 合并到一个 ServerRuntime的主要内容,如果未能解决你的问题,请参考以下文章
Apache Cayenne“类未与 Cayenne 映射”
我可以将 Cayenne 配置为使用提供程序来获取模型的新实例吗?