属性容器

InstancePropertyContainerCollectionPropertyContainer 是设计用来处理实体实例和集合,这些实体实例和集合是其他实体的属性。

在 XML 描述中可以这样定义属性容器:

<instance id="userDc"
          class="com.company.onboarding.entity.User"> (1)
    <fetchPlan extends="_base">
        <property name="department" fetchPlan="_base"/>
        <property name="steps" fetchPlan="_base">
            <property name="step" fetchPlan="_base"/>
        </property>
        <property name="hobbies" fetchPlan="_base"/>
    </fetchPlan>
    <loader/>
    <collection id="stepsDc" property="steps"/> (2)
</instance>
1 InstanceContainer 保存 User 的一个实例,实体具有 steps 属性。
2 CollectionPropertyContainer 保存 UserStep 的实例集合,该集合位于 Employee 实体的 steps 属性。

方法

属性容器实现了 Nested 接口,这个接口定义了获取主容器方法,以及获取此属性容器绑定的主容器属性名称的方法。在 UserUserStep 实体的例子中,主容器是用来存储 User 实例的容器。

InstancePropertyContainer 可以直接跟主实体的属性交互。也就是说,如果调用 setItem() 方法,这个值会直接设置到相应主实体的属性,同时主实体的 ItemPropertyChangeEvent 监听器会被触发。

CollectionPropertyContainer 包含主集合的拷贝,它的方法行为如下:

  • getMutableItems() 返回实体的可变列表,对列表的改动都会反映到主实体的属性。也就是说,如果从列表中删除了一项,主实体的属性也会更改,主容器的 ItemPropertyChangeEvent 监听器会触发。

  • getDisconnectedItems() 返回实体的可变列表,但是这个列表内的改动不会反映到主实体的属性。也就是说如果从这个列表中删除了一项,主实体属性不变。

  • setItems() 为容器设置实体集合,同时也设置给了关联的主属性。因此,主容器的 ItemPropertyChangeEvent 监听器会被触发。

  • setDisconnectedItems() 为容器设置实体集合,但是底层关联的主属性不变。

getDisconnectedItems()setDisconnectedItems() 方法可以用来暂时改变集合在 UI 的展示,比如对表格做过滤:

@ViewComponent
private CollectionPropertyContainer<UserStep> stepsDc;
@Autowired
private MetadataTools metadataTools;

private void filterByDueDate(LocalDate dueDate) {
    List<UserStep> filtered = getEditedEntity().getSteps().stream()
            .filter(userStep -> userStep.getDueDate().isAfter(dueDate))
            .collect(Collectors.toList());
    stepsDc.setDisconnectedItems(filtered);
}

private void resetFilter() {
    stepsDc.setDisconnectedItems(getEditedEntity().getSteps());
}