仁者爱人,有礼者敬人。爱人者,人恒爱之;敬人者,人恒敬之。——孟子

前两天写了关联表更新封装

今天写个另一种类型的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
public static <T,
K extends Comparable<? super K> & Serializable,
A,
L extends Comparable<? super L> & Serializable>
BaseDbBO<A> saveAttach(AttachBO<T, K, A> bo) {
val mainList = bo.getMainList();

val mainKeys = Steam.of(mainList).map(bo.getMainKey()).toList();
val attachKeyExecutable = LambdaHelper.resolve(bo.getAttachKey());
val attachKeySetter = getSetter(attachKeyExecutable);
val compareGetterSetterMap = Steam.of(bo.getAttachCompares())
.toMap(Function.identity(), MpUtil::getSetter);
val attachListFromClient = Steam.of(mainList).flat(m -> Steam.of(bo.getAttachGetter().apply(m))
.peek(a -> attachKeySetter.accept(a, bo.getMainKey().apply(m))))
.toList();
val attachGetterExecutable = LambdaHelper.resolve(bo.getAttachGetter());
val field = ReflectHelper.getField(attachGetterExecutable.getClazz(), BeanHelper.getPropertyName(attachGetterExecutable.getName()));
Class<A> genericType = (Class<A>) ReflectHelper.getGenericTypes(field.getGenericType())[0];
val attachListFromDb = Many.of(bo.getAttachKey()).in(mainKeys)
.value(v -> {
val vo = ((SerSupp<A>) genericType::newInstance).get();
BeanUtils.copyProperties(v, vo);
return vo;
})
.query();
val attachTableInfo = TableInfoHelper.getTableInfo(attachKeyExecutable.getClazz());
val attachPrimaryKey = MpUtil.<A, L>getGetter((Class<A>) attachKeyExecutable.getClazz(),
attachTableInfo.getKeyProperty());
val attachKeyListFromDb = Steam.of(attachListFromDb).map(attachPrimaryKey).toList();
if (attachKeyListFromDb.isEmpty()) {
bo.setWillInsertList(attachListFromClient);
bo.setDataList(attachListFromClient);
return bo;
}
if (attachListFromClient.isEmpty()) {
bo.setWillDeleteList(attachListFromDb);
return bo;
}
val mainIdAttachesMapFromDb = Steam.of(attachListFromDb).group(bo.getAttachKey());
val mainIdAttachesMapFromClient = Steam.of(attachListFromClient).group(bo.getAttachKey());
mainKeys.forEach(mainKey -> {
val attachesFromDb = mainIdAttachesMapFromDb.getOrDefault(mainKey, emptyList());
val attachesFromClient = mainIdAttachesMapFromClient.getOrDefault(mainKey, emptyList());
if (attachesFromDb.isEmpty() && attachesFromClient.isEmpty()) {
return;
}
if (attachesFromDb.isEmpty()) {
bo.getWillInsertList().addAll(attachesFromClient);
return;
}
if (attachesFromClient.isEmpty()) {
bo.getWillDeleteList().addAll(attachesFromDb);
return;
}
val idAttachMapFromDb = Steam.of(attachesFromDb).toMap(attachPrimaryKey);
// insert
Steam.of(attachesFromClient)
.filter(attach -> {
val id = attachPrimaryKey.apply(attach);
return Objects.isNull(id) || !idAttachMapFromDb.containsKey(id);
})
.forEach(bo.getWillInsertList()::add);
val idAttachMapFromClient = Steam.of(attachesFromClient)
.filter(attach -> {
val id = attachPrimaryKey.apply(attach);
return Objects.nonNull(id);
}).toMap(attachPrimaryKey);
// remove
val attachKeysFromDb = idAttachMapFromDb.keySet();
Steam.of(attachKeysFromDb)
.filter(id -> !idAttachMapFromClient.containsKey(id))
.map(idAttachMapFromDb::get)
.forEach(bo.getWillDeleteList()::add);
// modify
attachKeysFromDb.retainAll(idAttachMapFromClient.keySet());
attachKeysFromDb.forEach(attachKey -> {
val attachFromDb = idAttachMapFromDb.get(attachKey);
val attachFromClient = idAttachMapFromClient.get(attachKey);
if (Objects.nonNull(attachFromDb) && Objects.nonNull(attachFromClient)) {
Steam.of(bo.getAttachCompares()).forEach(ac -> {
val value = ac.apply(attachFromClient);
if (!Objects.equals(value, ac.apply(attachFromDb))) {
val executable = LambdaHelper.resolve((Serializable) ac);
val setter = compareGetterSetterMap.get(ac);
val fieldType = ReflectHelper.getField(executable.getClazz(),
BeanHelper.getPropertyName(executable.getName())).getType();
setter.accept(attachFromDb, value);
if (isComparable(fieldType) && (!bo.getWillUpdateList().contains(attachFromDb))) {
bo.getWillUpdateList().add(attachFromDb);

}
}
});
}
});
});
bo.setAfterExecuted(b -> {
attachListFromDb.removeIf(bo.getWillDeleteList()::contains);
attachListFromDb.addAll(bo.getWillInsertList());
val idAttachMap = Steam.of(attachListFromDb).toMap(attachPrimaryKey);
attachListFromClient.forEach(data -> {
val primaryKey = attachPrimaryKey.apply(data);
idAttachMap.put(primaryKey, data);
});
bo.setDataList(new ArrayList<>(idAttachMap.values()));
});
return bo;
}

使用起来也差不多

1
2
3
4
5
6
7
8
9
10
11
12
val cards = MpUtil.saveAttach(new AttachBO<ProductDetailVO, Long, ProductDetailCardVO>() {{
setMainList(vos);
setMainKey(ProductDetailVO::getId);
setAttachKey(ProductDetailCardVO::getDetailId);
setAttachGetter(ProductDetailVO::getCardList);
setAttachCompares(Lists.of(
ProductDetailCardVO::getType,
ProductDetailCardVO::getCanAdd,
ProductDetailCardVO::getViewMode,
ProductDetailCardVO::getDataList
));
}}).execute();