我将Apache Cayenne视为新应用程序的ORM层。
我的数据库模型的一部分将在一个固定模型中定义,该模型将在编译时知道。
但是,模型的另一部分将在运行时由某些有限的用户操作定义。因此,这些操作将产生创建某些简单表,添加和删除这些表中的列,删除表等的效果。
基于其通用的持久对象功能,似乎Cayenne非常适合这种情况。
https://cayenne.apache.org/docs/3.1/cayenne-guide/persistent-objects-objectcontext.html
我正在寻找一些示例,说明如何将用户定义的DbEntity引入Cayenne运行时,生成并运行CREATE / ALTER / DROP SQL,然后指定某些通用持久对象由某些特定的支持用户定义的表。
答案 0 :(得分:2)
是的,Cayenne通用对象可以在运行时更改模型。更新实际架构还有一个额外的挑战。描述中有一些未知数(多个应用程序/用户共享的基础数据库;模式的并发性发生变化;应用后需要在基础Cayenne模型中保留更改)。但这里有一个粗略的想法,我将如何处理这个问题:
每当用户准备好进行新的更改时,使用cayenne-project.jar library将受影响的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);
}
最后使用&#39; newRuntime&#39;替换原有版本的ServerRuntime。