动态属性 API
模型
动态属性实现了 实体-属性-值 模型。
-
Category指定对象的分类,以及每个分类对应的一组动态属性。每个分类需要与特定实体类型关联。例如,有一个
Car类型的实体。我们可以创建两个分类:Truck(卡车)和Passenger(乘用车)。Truck分类可以包含Load capacity(载货量)和Body type(车身类型)属性;Passenger分类可以包含Number of seats(座位数)和Child seat(儿童座位)属性。 -
CategoryAttribute定义某个分类中的动态属性。每个属性使用指定类型定义单一字段。必需的code字段包含属性的系统名称。name字段包含可读的属性名称。 -
CategoryAttributeValue表示特定实体实例中动态属性的值。动态属性值保存在专门的SYS_ATTR_VALUE表中。表中的记录通过ENTITY_ID列与一个实体实例关联。
一个实体实例可以拥有该实体类型关联的所有分类中的属性。因此,如果为上面提到的 Car 实体创建两个分类,则可以为 Car 实例指定两个分类中的任何属性。
如果需要将实体实例划分为某一特定分类,例如,车只能是卡车或乘用车之一,则实体必须实现 Categorized 接口。此时,实体只有特定分类的引用,且只能有该分类的动态属性。
读写动态属性
动态属性值的读写通过 DataManager 处理。使用下列方法之一可以设置加载实体的动态属性:
-
LoadContext的setHint(DynAttrQueryHints.LOAD_DYN_ATTR, true)方法。 -
流式 API 的
hint(DynAttrQueryHints.LOAD_DYN_ATTR, true)方法。
默认情况下,不加载动态属性。但是,DataManager 会保存 save() 方法中收到实体包含的动态属性。
动态属性值可以通过 EntityValues 的 getValue() / setValue() 方法进行读写。动态属性编码需要使用 + 前缀,示例:
@Autowired
private DataManager dataManager;
@ViewComponent
private DataGrid<Car> carsDataGrid;
public void increaseLoadCapacity(Car car, int value) {
Car carLoad = dataManager.load(Car.class)
.id(car.getId())
.hint(DynAttrQueryHints.LOAD_DYN_ATTR, true)
.one();
Integer capacity = EntityValues.getValue(car, "+truckLoadCapacity");
EntityValues.setValue(car, "+truckLoadCapacity", capacity + value);
dataManager.save(car);
}
实际编程时,我们几乎不在应用程序代码中直接访问动态属性值。任何动态属性都可以自动在 DataGrid 或 FormLayout 组件中展示,只要这些组件绑定的数据容器中实体带有动态属性。可以在配置动态属性时,指定界面和组件中动态属性的 可见性。