Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

支持直接填充 Map 类型的数据 #21

Closed
Createsequence opened this issue Mar 11, 2023 · 0 comments
Closed

支持直接填充 Map 类型的数据 #21

Createsequence opened this issue Mar 11, 2023 · 0 comments
Labels
enhancement New feature or request worth trying Features or improvements that are worth trying but not necessarily achievable
Milestone

Comments

@Createsequence
Copy link
Collaborator

Createsequence commented Mar 11, 2023

目前已经支持处理数据源对象为 Map 的情况,但是还不支持处理目标对象为 Map 的情况,需要调整代码以便完成对 Map 类型数据的全面支持,比如:

Map<Stirng, Object> fooToMap = new HashMap<>();
operateTemplate.execute(fooToMap, Foo.class);
operateTemplate.execute(Array.asList(fooToMap, fooToMap, fooToMap), Foo.class);

这一个/一批 Map 集合将会按 Foo.class 的配置进行填充。

此外,还需要在配置文件中提供 enable-operate-map 选项用于选择是否启动对 Map 类型的数据源和目标对象的支持。

其实现有的代码以及可以在不进行太大改动的前提下支持这个功能了,只要把目前的 AssembleOperationHandler 实现中,获取待处理对象类型的代码进行一点改动。

得益于目前装配处理器的代码结构,我们只需要分别修改顶层抽象模板中的少量代码即可让所有的处理器获得该能力:

  1. GenericReflexAssembleOperationHandler.collectToEntities:

    protected Collection<AssembleOperationTarget> collectToEntities(Collection<AssembleExecution> executions) {
        List<AssembleOperationTarget> targets = new ArrayList<>();
        for (AssembleExecution execution : executions) {
            String key = execution.getOperation().getKey();
            execution.getTargets().stream()
                // 直接获取实际待处理对象的类型
                .map(t -> createTarget(execution, t, propertyOperator.readProperty(t.getClass(), key, t)))
                .forEach(targets::add);
        }
        return targets;
    }
  2. GenericReflexAssembleOperationHandler.mappingProperty:

    private void mappingProperty(AssembleOperationTarget entity, Object source, PropertyMapping mapping) {
        Object sourceValue = mapping.hasSource() ?
            propertyOperator.readProperty(source.getClass(), source, mapping.getSource()) : source;
        if (Objects.nonNull(sourceValue)) {
            // 直接获取实际待处理对象的类型
            Object origin = entity.getOrigin();
            propertyOperator.writeProperty(origin.getClass(), origin, mapping.getReference(), sourceValue);
        }
    }
  3. OneToManyReflexAssembleOperationHandler.completeMapping:

    protected void completeMapping(Object source, AssembleOperationTarget target) {
        Collection<?> sources = CollectionUtils.adaptObjectToCollection(source);
        Set<PropertyMapping> mappings = target.getExecution().getOperation().getPropertyMappings();
        for (PropertyMapping mapping : mappings) {
            // there are always multiple source values,
            // so we need to merge the source objects after operation
            Collection<?> sourceValues = mapping.hasSource() ?
                sources.stream().map(s -> propertyOperator.readProperty(s.getClass(), s, mapping.getSource()))
                    .collect(Collectors.toList()) : sources;
            // 直接获取实际待处理对象的类型
            Object origin = entity.getOrigin();
            propertyOperator.writeProperty(origin.getClass(), origin, mapping.getReference(), sourceValues);
        }
    }

另外,考虑到需要直接填充 Map 集合的场景下多半没有对应的 Class,或许需要 OperateTemplate 会需要一个 execute(Object target, BeanOperations) 类型的重载方法,并提供一个可以在代码中手动构建,而不是一定要通过配置解析器获取的 BeanOperations 实现(类似 Spring 的 GenericBeanDefinition),在完成该 issues 后,可以考虑再另外提一个 issues 去完成这个额外想法。

@Createsequence Createsequence added enhancement New feature or request worth trying Features or improvements that are worth trying but not necessarily achievable labels Mar 11, 2023
@Createsequence Createsequence added this to the release 0.0.2-alpha milestone Mar 11, 2023
@Createsequence Createsequence changed the title Support filling in objects of type Map 支持直接填充 Map 类型的数据 Mar 16, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request worth trying Features or improvements that are worth trying but not necessarily achievable
Projects
None yet
Development

No branches or pull requests

1 participant