是的,Cayenne 通用对象可以在运行时更改您的模型。您有一个额外的挑战来更新实际的架构。描述中有一些未知数(多个应用程序/用户共享的底层数据库;架构更改的并发性;应用后是否需要将更改保留在底层 Cayenne 模型中)。但这里是我将如何处理这个的粗略想法:
每当用户准备好进行新更改时,使用cayenne-project.jar 库将受影响的 cayenne-project.xml 与 ServerRuntime 分开加载。
Injector i = DIBootstrap.createInjector(new CayenneProjectModule());
ProjectLoader loader = i.getInstance(ProjectLoader.class);
Project p = loader.loadProject(new URLResource(..));
做出改变:
ConfigurationNodeVisitor mapChangeAction = .. // implement this to make your changes
p.getRootNode().acceptVisitor(mapChangeAction);
保存回文件系统:
i.getInstance(ProjectSaver.class).save(p);
现在您可以使用新模型创建第二个 ServerRuntime,然后使用 org.apache.cayenne.merge 包中的 API 对 DB 运行迁移。您可以使用 DbAdapter.mergerFactory() 根据上面所做的更改创建 MergeToken,然后执行它们:
DataDomain domain = newRuntime.getDataDomain();
DataNode node = domain.getDataNode("nodename");
DataMap map = domain.getDataMap("mapname");
List<MergerToken> tokens = ...
MergerContext mergerContext = new ExecutingMergerContext(map, node);
for (MergerToken tok : tokens) {
tok.execute(mergerContext);
}
最后用'newRuntime'替换你原来的旧模型的ServerRuntime。