0

我正在将 Apache Cayenne 作为我的新应用程序的 ORM 层。

我的部分数据库模型将在一个固定模型中定义,该模型将在编译时知道。

但是,模型的另一部分将在运行时由某些有限的用户操作定义。因此,这些操作将产生创建某些简单表、在这些表中添加和删除列、删除表等的效果。

基于其通用的持久对象特性,Cayenne 似乎非常适合这一点。

https://cayenne.apache.org/docs/3.1/cayenne-guide/persistent-objects-objectcontext.html

我正在寻找一些示例,说明如何将用户定义的 DbEntity 引入 Cayenne 运行时,生成并运行 CREATE / ALTER / DROP SQL,然后指定某些通用持久对象由某些用户定义的表支持。

4

1 回答 1

2

是的,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。

于 2015-06-15T07:10:36.213 回答