og 。这三个表都是通过 item:item_core_id 来关联的,在 item 表是 item:item_core_id 字段, 在 item_price 表是 item_price:item_id 字段, 在 item_price_change_log 表是 item_price_change_log:item_id 字段。
提示
基本思路是:
STEP1: 对于含有表 item, item_core, item_price, item_price_change_log 数据的指定JSON,构建一个总的 itemIndexMap[table:id, Map[table:field, value]],其中 key 是 table:id, value 是一个 valMap, valMap 的键是 table:field, 值是对应的最后面的值。 table: 作为名字空间的前缀,是为了避免不同表之间的ID和field相互重合覆盖。 见方法 buildItemIndexMap 的实现。
STEP2: 从 itemIndexMap 构建 item:id 与 item:item_core_id 的映射 itemCoreId2originItemIdMap;在实际应用中, originItemId 为 oldItemId (item:id), itemCoreId 为 newItemId (item:item_core_id);
STEP3: 对于每一个 [table:id, Map[table:field, value]], 通过 itemCoreId2originItemIdMap 拿到对应的 originitemId , 然后使用 originitemId 为键替换itemIndexMap中对应的 item_core:id, item_price:id, item_price_change_log:id,将具有相同的 originItemId 的不同的 Map[table:field, value] 进行合并后,添加到新的newItemIndexMap 中。
程序实现
初步实现
ItemUtil.java
package zzz.study.utils;
/**
* Created by shuqin on 17/11/10.
*/
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import static zzz.study.utils.NewMapUtil.merge;
/**
* Created by shuqin on 17/10/23.
*/
public class ItemUtil {
private static Logger logger = LoggerFactory.getLogger(ItemUtil.class);
/**
* 构建一个订单的所有商品级别的信息以及映射
* @param multiItemInfoMapForOneOrder 一个订单下多个商品的信息
* @return 一个订单的所有商品级别的信息以及映射
*
* key 是 sID + order_no + item_id ; item_id 对应 item.id, 对应 item_core.item_core_id
*/
public static Map<String, Map<String,Object>> buildFinalOrderItemMap(Map<String,String> multiItemInfoMapForOneOrder) {
try {
return mergeOrderItemMap(buildItemIndexMap(multiItemInfoMapForOneOrder));
} catch (Exception ex) {
logger.error("failed to buildFinalOrderItemMap for: " + multiItemInfoMapForOneOrder, ex);
return new HashMap<>();
}
}
/**
* 构建一个订单的所有商品级别的信息以及映射
* @param itemInfoMap 商品级别的信息
* @return 一个订单的所有商品的信息
*
* NOTE: itemInfoMap 是对应一个订单的所有商品的信息的映射,不要传多个订单的信息进来,可能重复
*
* key = table:table_unique_id , value = map [ table:field, value ]
*
* eg. map [ item:goods_type:1800888 = 0 , item:num:1800888 = 8 ]
* will be transformed into map[item:1800888 = map[item:goods_type=0 , item:num=8]]
*/
public static Map<String,Map<String,String>> buildItemIndexMap(Map<String, String> itemInfoMap) {
Map<String, Map<String,String>> itemIndexMap = new HashMap<>();
itemInfoMap.forEach(
(key, value) -> {
String[] keyparts = key.split(":");
// 只考虑三段式 tablename:field:id
if (keyparts != null && keyparts.length == 3) {
String table = keyparts[0];
String field = keyparts[1];
String index = keyparts[2];
String indexKey = table+ ":" + index;
String fieldKey = table+":"+field;
if (itemIndexMap.get(indexKey) == null) {
itemIndexMap.put(indexKey, new HashMap<>());
}
itemIndexMap.get(indexKey).put(fieldKey, String.valueOf(value));
}
}
);
return itemIndexMap;
}
/**
* 聚合一个订单下的所有商品信息
* @param itemIndexMap 一个订单所有商品的信息映射
* @return 一个订单下的所有商品信息
*
* key 是 sID + order_no + item_id ; item_id 对应 item.id, item_core.item_core_id
*/
private static Map<String, Map&l