3.4.2. 数据存储
在 CUBA 应用程序中处理数据的常用方法是操作实体 - 可通过数据源和具有数据感知功能的可视化组件进行声明式处理,也可通过 DataManager 或 EntityManager 进行编程式处理。实体映射到数据存储中的数据,数据存储通常是关系型数据库。应用程序可以连接到多个数据存储,因此其数据模型将包含映射到位于不同数据库中的数据的实体。
实体只能属于单个数据存储,但是可以在单个 UI 界面上显示来自不同数据存储的实体,DataManager 可以确保在保存时将实体分派到适当的数据存储中去。根据实体类型,DataManager 选择一个已注册的数据存储,这个数据存储实现了 DataStore 接口,然后委托其加载和保存实体。当以编程的方式控制事务并通过 EntityManager 使用实体时,必须明确指定要使用的数据存储。有关详细信息,请参阅 Persistence 接口方法和 @Transactional 注解参数。
平台提供了 DataStore 接口的单一实现,名称为 RdbmsStore,这个实现的目的是通过 ORM 层来使用关系型数据库。可以在自己的项目中实现 DataStore 接口以进行数据整合,例如,可以与非关系型数据库或具有 REST 接口的外部系统进行数据整合。
在任何 CUBA 应用程序中,必定存在一个主数据存储,它包含系统实体和安全实体,用户登录也是在主数据存储。在本手册中提及数据库时,如果没有明确说明,则指的是主数据存储。主数据存储必须是通过 JDBC 数据源连接的关系型数据库。主数据源位于 JNDI 中,其名称应在 cuba.dataSourceJndiName 应用程序属性中指定,默认情况下为 jdbc/CubaDS。
可以在 cuba.additionalStores 应用程序属性中指定其它附加数据存储名称。如果附加存储是 RdbmsStore,需要提供以下属性:
-
cuba.dataSourceJndiName_{store_name}- 相应 JDBC 数据源的 JNDI 名称。 -
cuba.dbmsType_{store_name}- 数据存储 DBMS 的类型。 -
cuba.persistenceConfig_{store_name}- 数据存储persistence.xml文件的位置。
如果在项目中为附加存储实现了 DataStore 接口,需要在 cuba.storeImpl_{store_name} 应用程序属性中指定实现 bean 的名称。
例如,如果需要使用另外两个数据存储:db1(PostgreSQL 数据库)和 mem1(由某个项目 bean 实现的内存存储),请在 core 模块的 app.properties 中指定以下应用程序属性:
cuba.additionalStores = db1, mem1
cuba.dataSourceJndiName_db1 = jdbc/db1
cuba.dbmsType_db1 = postgres
cuba.persistenceConfig_db1 = com/company/sample/db1-persistence.xml
cuba.storeImpl_mem1 = sample_InMemoryStore
还应在所有应用程序 block 使用的属性文件(web-app.properties、 portal-app.properties 等)中指定 cuba.additionalStores 和 cuba.persistenceConfig_db1 属性。
|
CUBA Studio 允许在 CUBA Project Properties 窗口的 Data Stores 标签页上设置其它数据存储。它会自动创建所有必须的应用程序属性和 JDBC 数据源,同时维护额外的 |
- 来自不同数据存储的实体之间的引用
-
如果正确定义了 DataManager,则可以自动维护来自不同数据存储的实体之间的 TO-ONE 引用。比如,在主数据存储中有
Order实体,在附加数据存储中有Customer实体,并且希望在Order中引用Customer。可以这样做:-
在
Order实体中,定义一个存储Customer实体 ID 的属性。该属性应使用@SystemLevel注解,以将其从用户可用的各种列表中排除,例如 Filter 中的可选属性:@SystemLevel @Column(name = "CUSTOMER_ID") private Long customerId; -
在
Order实体中,定义对Customer的非持久引用,并将 "related" 指定为customerId:@Transient @MetaProperty(related = "customerId") private Customer customer; -
在适当的视图中包含非持久化的
customer属性。
之后,当使用包含
customer属性的视图加载Order时,DataManager会自动从附加数据存储加载关联的Customer。集合的加载针对性能进行了优化:在加载 Order 列表之后,从附加数据存储加载引用的 Customer 是分批完成的。每批加载的记录数由 cuba.crossDataStoreReferenceLoadingBatchSize 应用程序属性定义。当提交引用了
Customer的Order实体图时,DataManager会通过相应的DataStore进行数据保存,然后将 Customer 的 ID 保存在 Order 的customerId属性中。Filter 组件也支持跨数据存储引用。
在 Studio 中,如果使用了跨数据存储的实体引用属性,Studio 会自动维护这种引用关系。
-