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); 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); val attachKeysFromDb = idAttachMapFromDb.keySet(); Steam.of(attachKeysFromDb) .filter(id -> !idAttachMapFromClient.containsKey(id)) .map(idAttachMapFromDb::get) .forEach(bo.getWillDeleteList()::add); 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; }
|