Apache Cayenne:使用动态提供的DataMap将固定的合并到一个ServerRuntime中

时间:2018-07-16 13:08:57

标签: apache-cayenne

我的应用程序设计包含固定和动态的DataMap,以连接到不同的(Oracle)数据库实例/用户。为简单起见,我确实将它们分为两个不同的Cayenne项目。

  1. 使用固定的DataMap创建ServerRuntimeBuilder,构建并查询我的客户表。
  2. 对于每个客户,通过第二次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项目创建最终的ServerRuntime。
ServerRuntime 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 个答案:

答案 0 :(得分:0)

我将启动runtime1以获取配置数据,然后创建包含固定和动态映射以及自定义DataMap加载器以动态重写名称和架构的runtime2:

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,因此最后只有一个运行时。