今天是另外一种类型的关联更新封装
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
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
,临时放到另一个仓库里