关联更新封装(三)

2023-03-20 10:37:32 浏览数 (1)

今天是另外一种类型的关联更新封装

代码语言:javascript复制
public static <T, K extends Comparable<? super K> & Serializable, S> BaseDbBO<S> saveSub(SubBO<T, K, S> bo) {
        val subIds = Steam.of(bo.getMainList())
                .flat(data -> Steam.of(bo.getSubIdGetters()).map(f -> f.apply(data)))
                .nonNull().toList();
        val subClazz = (Class<S>) Steam.of(bo.getSubGetters())
                .findFirst()
                .map(LambdaHelper::resolve)
                .map(LambdaExecutable::getReturnType)
                .orElseThrow(() -> new IllegalStateException("sub class not found"));
        val primaryKeyGetter = MpUtil.<S, K>getGetter(subClazz,
                TableInfoHelper.getTableInfo(subClazz).getKeyProperty());
        val idSubMapFromDb = subIds.isEmpty() ? new HashMap<K, S>() :
                Steam.of(Database.listByIds(subIds, subClazz)).toMap(primaryKeyGetter);
        val subIdGetterSetterMap = Steam.of(bo.getSubIdGetters())
                .toMap(Function.identity(), MpUtil::getSetter);
        val comparesGetterSetterMap = Steam.of(bo.getSubCompares())
                .toMap(Function.identity(), MpUtil::getSetter);

        Steam.of(bo.getMainList()).forEach(data ->
                Steam.of(bo.getSubIdGetters()).zip(bo.getSubGetters(),
                        (subIdGetter, subGetter) -> {
                            val subFromClient = subGetter.apply(data);
                            val subId = subIdGetter.apply(data);
                            if (Objects.isNull(subFromClient)) {
                                return null;
                            }
                            // insert
                            if (Objects.isNull(subId)) {
                                bo.getWillInsertList().add(subFromClient);
                                return subFromClient;
                            }
                            val subFromDb = idSubMapFromDb.get(subId);
                            if (Objects.isNull(subFromDb)) {
                                bo.getWillInsertList().add(subFromClient);
                                return subFromClient;
                            }
                            // update
                            Steam.of(bo.getSubCompares()).forEach(ac -> {
                                val value = ac.apply(subFromClient);
                                if (!Objects.equals(value, ac.apply(subFromDb))) {
                                    val executable = LambdaHelper.resolve((Serializable) ac);
                                    val setter = (BiConsumer<S, Object>) comparesGetterSetterMap.get(ac);
                                    val fieldType = ReflectHelper.getField(executable.getClazz(),
                                            BeanHelper.getPropertyName(executable.getName())).getType();
                                    setter.accept(subFromDb, value);
                                    if (isComparable(fieldType)) {
                                        if (!bo.getWillUpdateList().contains(subFromDb)) {
                                            bo.getWillUpdateList().add(subFromDb);
                                        }
                                    }
                                }
                            });
                            return subFromClient;
                        }).toList());
        bo.setAfterExecuted(b -> {
            val dataList = Steam.of(bo.getMainList()).flat(data ->
                    Steam.of(bo.getSubIdGetters()).zip(bo.getSubGetters(),
                            (subIdGetter, subGetter) -> {
                                S subFromClient = subGetter.apply(data);
                                if (Objects.nonNull(subFromClient)) {
                                    val primaryKey = primaryKeyGetter.apply(subFromClient);
                                    subIdGetterSetterMap.get(subIdGetter).accept(data, primaryKey);
                                }
                                return subFromClient;
                            }).nonNull().toList()).toList();
            bo.setDataList(dataList);
        });
        return bo;
    }

对应的bo

代码语言:javascript复制
package com.ruben.simplestreamquery.pojo.bo;

import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 * @author VampireAchao
 * @since 2023/3/16 10:18
 */
@Data
@EqualsAndHashCode(callSuper = true)
public class SubBO<T, K extends Comparable<? super K> & Serializable, S> extends BaseDbBO<S> {

    private List<T> mainList;
    private List<SFunction<T, K>> subIdGetters;
    private List<SFunction<T, S>> subGetters;
    private List<SFunction<S, ?>> subCompares;

    public SubBO() {
        super();
        this.mainList = new ArrayList<>();
        this.subIdGetters = new ArrayList<>();
        this.subGetters = new ArrayList<>();
        this.subCompares = new ArrayList<>();
    }
}

目前仍然处于完善中,所以还没有集成进stream-query,临时放到另一个仓库里

地址

0 人点赞