3.9.1. 动态属性
Dynamic attributes - 动态属性 是额外的实体属性,可以在不需要修改数据库表结构或者重启应用的情况下为实体添加。动态属性通常用来在部署或者生产阶段为实体定义新属性。
CUBA 动态属性实现了 Entity-Attribute-Value 模型。
-
Category
- 定义对象的一个 category - 类别 以及相应的一组动态属性。这个类别必须分配给某些实体类型。比如,有个实体是 Car 类型的。可以为它定义两个类别:卡车(Truck)和客车(Passenger)。卡车类别需要包含载重量和车身类型属性,客车类别需要包含座位数和儿童座位属性。
-
CategoryAttribute
- 定义关联某些类别的动态属性。每个属性需要为一个明确类型描述一个字段。必要的Code
字段包含属性的系统名称。Name
字段包含具有可读性的名称。 -
CategoryAttributeValue
- 特定实体实例动态属性的值。动态属性值物理存储在专门的SYS_ATTR_VALUE
表内。表的每一行都有指向某些实体的 id(ENTITY_ID
列)。
一个实体实例可以拥有跟这个实体类型相关的所有类别的动态属性。所以如果按照上面创建了两个关于 Car 的类别,则可以为一个 Car 实例定义两种类别中的任何动态属性。如果需要将实体实例分类到具体的某一类别(比如 Car 可以是卡车或者客车),那么实体需要实现 Categorized 接口。这样实体实例就会有指向类别的引用,也只能包含此类别的动态属性。
加载和保存动态属性是通过 DataManager 来处理的。LoadContext
的 setLoadDynamicAttributes()
方法或流式 API 的 dynamicAttributes()
方法可以用来设置是否需要为实体实例加载动态属性。默认情况下,不会加载动态属性。同时,DataManager
总是会保存传递给 commit()
方法的实体实例的动态属性。
对于任何继承自 BaseGenericIdEntity
的持久化实体,动态属性的值可以通过 getValue()
/ setValue()
方法来读写。此时,需要给方法传递一个带 +
前缀的属性 code。示例:
Car entity = dataManager.load(Car.class).id(carId).dynamicAttributes(true).one;
Double capacity = entity.getValue("+loadCapacity");
entity.setValue("+loadCapacity", capacity + 10);
dataManager.commit(entity);