找回密码
 立即注册
首页 业界区 业界 商品中心—7.自研缓存框架的技术文档

商品中心—7.自研缓存框架的技术文档

睿哝 昨天 13:56
大纲
1.商品C端系统监听商品变更及刷新缓存
2.自研缓存框架的数据表缓存组件
3.自研缓存框架的通用缓存读写组件与DB操作组件
 
1.商品C端系统监听商品变更及刷新缓存
FlushRedisCache的flushRedisStringData()方法刷新缓存的逻辑是:首先从DB查询最新的数据 -> 然后删除旧缓存 -> 最后更新缓存。
  1. @Configuration
  2. public class ConsumerBeanConfig {
  3.     //配置内容对象
  4.     @Autowired
  5.     private RocketMQProperties rocketMQProperties;
  6.    
  7.     //监听商品修改的MQ消息
  8.     @Bean("productUpdateTopic")
  9.     public DefaultMQPushConsumer productUpdateTopic(ProductUpdateListener productUpdateListener) throws MQClientException {
  10.         DefaultMQPushConsumer consumer = new DefaultMQPushConsumer(RocketMqConstant.PRODUCT_UPDATE_CONSUMER_GROUP);
  11.         consumer.setNamesrvAddr(rocketMQProperties.getNameServer());
  12.         consumer.subscribe(RocketMqConstant.PRODUCT_UPDATE_TOPIC, "*");
  13.         consumer.registerMessageListener(productUpdateListener);
  14.         consumer.start();
  15.         return consumer;
  16.     }
  17. }
  18. //商品变更时的缓存处理
  19. @Component
  20. public class ProductUpdateListener implements MessageListenerConcurrently {
  21.     @DubboReference(version = "1.0.0")
  22.     private TableDataUpdateApi tableDataUpdateApi;
  23.    
  24.     @Override
  25.     public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> list, ConsumeConcurrentlyContext consumeConcurrentlyContext) {
  26.         try {
  27.             for (MessageExt messageExt : list) {
  28.                 //消息处理这里,涉及到sku的缓存更新以及对应的整个商品明细的缓存更新
  29.                 String msg = new String(messageExt.getBody());
  30.                 log.info("执行商品缓存数据更新逻辑,消息内容:{}", msg);
  31.   
  32.                 TableDataChangeDTO tableDataChangeMessage = JsonUtil.json2Object(msg, TableDataChangeDTO.class);
  33.                 //更新sku对应的商品缓存信息
  34.                 tableDataUpdateApi.tableDataChange(tableDataChangeMessage);
  35.                 //发送回调消息通知
  36.                 tableDataUpdateApi.sendCallbackMessage(tableDataChangeMessage);
  37.             }
  38.         } catch (Exception e) {
  39.             log.error("consume error, 商品缓存更新失败", e);
  40.             //本次消费失败,下次重新消费
  41.             return ConsumeConcurrentlyStatus.RECONSUME_LATER;
  42.         }
  43.         return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
  44.     }
  45. }
  46. //商品信息变更服务
  47. @DubboService(version = "1.0.0", interfaceClass = TableDataUpdateApi.class, retries = 0)
  48. public class TableDataUpdateApiImpl implements TableDataUpdateApi {
  49.     @Resource
  50.     private FlushRedisCache flushRedisCache;
  51.    
  52.     private ExecutorService executorService = Executors.newFixedThreadPool(10);
  53.    
  54.     //商品表数据变更逆向更新缓存
  55.     @Override
  56.     public JsonResult tableDataChange(TableDataChangeDTO tableDataChangeDTO) {
  57.         executorService.execute(() -> {
  58.             try {
  59.                 //刷新缓存数据
  60.                 flushRedisCache.flushRedisStringData(false, tableDataChangeDTO.getTableName(), Sets.newHashSet(tableDataChangeDTO.getKeyId()));
  61.             } catch (Exception e) {
  62.                 log.error("刷新string类型缓存异常,入参为tableDataChangeDTO={}", tableDataChangeDTO, e);
  63.             }
  64.             try {
  65.                 flushRedisCache.flushRedisSetData(false, tableDataChangeDTO.getTableName(), Sets.newHashSet(tableDataChangeDTO.getKeyId()));
  66.             } catch (Exception e) {
  67.                 log.error("刷新set类型缓存异常,入参为tableDataChangeDTO={}", tableDataChangeDTO, e);
  68.             }
  69.             try {
  70.                 flushRedisCache.flushRedisSortedSetData(false, tableDataChangeDTO.getTableName(), Sets.newHashSet(tableDataChangeDTO.getKeyId()));
  71.             } catch (Exception e) {
  72.                 log.error("刷新sortedset类型缓存异常,入参为tableDataChangeDTO={}", tableDataChangeDTO, e);
  73.             }
  74.         });
  75.         return JsonResult.buildSuccess();
  76.     }
  77.     ...
  78. }
  79. //数据变更—刷新缓存
  80. @Component
  81. public class FlushRedisCache {
  82.     //继承了AbstractRedisStringCache的缓存实例会被注入到abstractRedisStringCacheMap这个map中
  83.     //例如CategoryBaseCache、FrontCategoryCache、ItemCollectCache、ProductDetailCache、SkuCollectCache等
  84.     @Autowired
  85.     private Map<String, AbstractRedisStringCache> abstractRedisStringCacheMap;
  86.    
  87.     //更新string类型缓存
  88.     //@param flushAll  是否全量刷新
  89.     //@param tableName 表名
  90.     //@param idSet     主键ID集合
  91.     public void flushRedisStringData(boolean flushAll, String tableName, Set<Long> idSet) {
  92.         for (Map.Entry<String, AbstractRedisStringCache> entry : abstractRedisStringCacheMap.entrySet()) {
  93.             AbstractRedisStringCache stringCache = entry.getValue();
  94.             if (flushAll) {
  95.                 stringCache.flushRedisStringDataByTableUpdateData();
  96.                 continue;
  97.             }
  98.             //继承AbstractRedisStringCache的每个缓存实例都指定来表名,如下用于匹配出对应的缓存实例
  99.             if (stringCache.getTableName().contains(tableName)) {
  100.                 stringCache.flushRedisStringDataByTableAndIdSet(tableName, idSet);
  101.             }
  102.         }
  103.     }
  104.     ...
  105. }
  106. //Redis(string)缓存抽象类
  107. public abstract class AbstractRedisStringCache<DO, BO> {
  108.     @Resource
  109.     private RedisReadWriteManager redisReadWriteManager;
  110.     ...
  111.    
  112.     //刷新缓存—根据主表ID集合(关联表变更需要查询主表)
  113.     public void flushRedisStringDataByTableAndIdSet(String tableName, Set<Long> idSet) {
  114.         Optional<Set<Long>> idSetOpt = getStringDatabase().getTableIdSetByRelationTableIdSet(tableName, idSet);
  115.         if (!idSetOpt.isPresent()) {
  116.             return;
  117.         }
  118.         flushRedisStringDataByIdSet(idSetOpt.get());
  119.     }
  120.    
  121.     //刷新缓存—根据主键ID集合
  122.     //@param idSet 数据表主键ID
  123.     private void flushRedisStringDataByIdSet(Set<Long> idSet) {
  124.         //根据id集合从数据库中查询出数据
  125.         Optional<RedisStringCache<DO>> stringSourceOpt = getStringDatabase().listTableDataByIdSet(idSet, queryType());
  126.         if (!stringSourceOpt.isPresent()) {
  127.             return;
  128.         }
  129.         RedisStringCache<DO> redisStringCache = stringSourceOpt.get();
  130.         if (!CollectionUtils.isEmpty(redisStringCache.getDeleteSet())) {
  131.             //通过缓存读写组件删除缓存
  132.             redisReadWriteManager.delete(redisStringCache.getDeleteSet().stream().map(this::getRedisKey).collect(toSet()).toArray(new String[]{}));
  133.         }
  134.         if (CollectionUtils.isEmpty(redisStringCache.getAddList())) {
  135.             return;
  136.         }
  137.         List<BO> boList = convertDO2BO(redisStringCache.getAddList());
  138.         Map<String, BO> redisMap = convertBO2Map(boList);
  139.         //通过缓存读写组件写入缓存
  140.         redisReadWriteManager.batchWriteRedisString(redisMap);
  141.     }
  142.     ...
  143. }
  144. //缓存读写管理
  145. @Service
  146. public class RedisReadWriteManager {
  147.     @Resource
  148.     private RedisCache redisCache;
  149.     ...
  150.    
  151.     //删除指定的key
  152.     public void delete(String... keys) {
  153.         Arrays.asList(keys).stream().forEach(key -> redisCache.delete(key));
  154.     }
  155.    
  156.     //批量添加string缓存
  157.     public <T> void batchWriteRedisString(Map<String, T> redisMap) {
  158.         List<Map.Entry<String, T>> list = Lists.newArrayList(redisMap.entrySet());
  159.         try {
  160.             for (List<Map.Entry<String, T>> entries : Lists.partition(list, PAGE_SIZE_100)) {
  161.                 for (Map.Entry<String, T> entry : entries) {
  162.                     redisCache.setex(true, entry.getKey(), JSON.toJSONString(entry.getValue()), RedisKeyUtils.redisKeyRandomTime(INT_EXPIRED_SEVEN_DAYS));
  163.                 }
  164.                 try {
  165.                     Thread.sleep(SLEEP_100);
  166.                 } catch (InterruptedException e) {
  167.                     e.printStackTrace();
  168.                 }
  169.             }
  170.         } catch (Exception e) {
  171.             log.error("批量添加string缓存异常 redisMap={}", redisMap, e);
  172.         }
  173.     }
  174.     ...
  175. }
复制代码
 
2.自研缓存框架的数据表缓存组件
(1)自研缓存框架的目录结构
(2)通过注解实现继承同一个抽象类的数据表缓存组件实例自动注入Map
 
(1)自研缓存框架的目录结构
1.png
(2)通过注解实现继承同一个抽象类的数据表缓存组件实例自动注入Map
继承AbstractRedisStringCache的数据表缓存组件实例会被注入到Map中,之后通过Map便可以根据表名来获取对应的数据表缓存组件实例了。数据表缓存组件实例中会封装一些获取DB数据表数据、获取缓存key等方法,而其继承的抽象类会提供一些根据DB获取缓存、刷新缓存等模版方法。
  1. @Component
  2. public class FlushRedisCache {
  3.     //继承了AbstractRedisStringCache的缓存实例会被注入到abstractRedisStringCacheMap这个map中
  4.     //例如CategoryBaseCache、FrontCategoryCache、ItemCollectCache、ProductDetailCache、SkuCollectCache等
  5.     @Autowired
  6.     private Map<String, AbstractRedisStringCache> abstractRedisStringCacheMap;
  7.     //继承了AbstractRedisSortedSetCache的缓存实例会被注入到abstractRedisSortedSetCacheMap这个map中
  8.     //例如SkuSellerCache
  9.     @Autowired
  10.     private Map<String, AbstractRedisSortedSetCache> abstractRedisSortedSetCacheMap;
  11.     ...
  12. }
  13. @Service("productDetailCache")
  14. public class ProductDetailCache extends AbstractRedisStringCache<ProductDetailDO, ProductDetailBO> {
  15.     //DB操作组件
  16.     @Resource
  17.     private ProductDetailStringDatabase productDetailStringDatabase;
  18.    
  19.     @Resource
  20.     private ProductDetailConverter productDetailConverter;
  21.    
  22.     @Override
  23.     protected RedisStringDatabase<ProductDetailDO> getStringDatabase() {
  24.         return productDetailStringDatabase;
  25.     }
  26.    
  27.     @Override
  28.     protected String getPendingRedisKey() {
  29.         return AbstractRedisKeyConstants.PRODUCT_SKU_INFO_STRING;
  30.     }
  31.    
  32.     @Override
  33.     protected List<ProductDetailBO> convertDO2BO(Collection<ProductDetailDO> doList) {
  34.         return productDetailConverter.converterDetailList(doList);
  35.     }
  36.    
  37.     @Override
  38.     protected Map<String, Object> getTableFieldsMap(String key) {
  39.         Map<String, Object> dbInputMap = Maps.newHashMap();
  40.         dbInputMap.put(SkuCollectStringDatabase.SKU_ID, key);
  41.         return dbInputMap;
  42.     }
  43.    
  44.     @Override
  45.     protected Class<ProductDetailBO> getBOClass() {
  46.         return ProductDetailBO.class;
  47.     }
  48.     ...
  49. }
  50. //Redis(string)缓存抽象类
  51. //@param <DO> 数据对象
  52. //@param <BO> 缓存对象
  53. public abstract class AbstractRedisStringCache<DO, BO> {
  54.     @Resource
  55.     private RedisReadWriteManager redisReadWriteManager;
  56.    
  57.     //获取redis key
  58.     //@param key 需要替换的关键字
  59.     protected String getRedisKey(String key) {
  60.         return String.format(getPendingRedisKey(), key);
  61.     }
  62.    
  63.     //单个获取数据库表名
  64.     public String getTableName() {
  65.         return getStringDatabase().getTableName();
  66.     }
  67.    
  68.     //获取DB读取对象
  69.     protected abstract RedisStringDatabase<DO> getStringDatabase();
  70.    
  71.     //获取待处理的Redis key
  72.     protected abstract String getPendingRedisKey();
  73.    
  74.     //DO转BO
  75.     protected abstract List<BO> convertDO2BO(Collection<DO> doList);
  76.    
  77.     //关联表字段值
  78.     protected abstract Map<String, Object> getTableFieldsMap(String key);
  79.    
  80.     //获取BO对象的class
  81.     protected abstract Class<BO> getBOClass();
  82.     ...
  83.    
  84.     //模版方法:根据关键字批量获取数据
  85.     //@param useLocalCache 是否使用本地缓存
  86.     //@param keyList       入参关键字
  87.     public Optional<List<BO>> listRedisStringData(Boolean useLocalCache, List<String> keyList) {
  88.         if (CollectionUtils.isEmpty(keyList)) {
  89.             return Optional.empty();
  90.         }
  91.         Optional<List<BO>> boListOpt = redisReadWriteManager.listRedisStringDataByCache(useLocalCache, keyList,
  92.             getBloomKey(), getStringDatabase()::getTableSingleFiled, getStringDatabase().getBloomField(),
  93.             getBOClass(), this::getRedisKey, (key) -> {
  94.                 Map<String, Object> tableFieldsMap = getTableFieldsMap(key);
  95.                 Optional<DO> doOpt;
  96.                 try {
  97.                     doOpt = getStringDatabase().getTableData(tableFieldsMap, queryType());
  98.                 } catch (Exception e) {
  99.                     log.error("根据关键字批量获取数据异常 key={},paramMap={}", key, tableFieldsMap, e);
  100.                     return Optional.empty();
  101.                 }
  102.                 if (!doOpt.isPresent()) {
  103.                     return Optional.empty();
  104.                 }
  105.                 List<BO> boList = convertDO2BO(Arrays.asList(doOpt.get()));
  106.                 if (CollectionUtils.isEmpty(boList)) {
  107.                     return Optional.empty();
  108.                 }
  109.                 return Optional.of(boList.get(0));
  110.             }
  111.         );
  112.         return boListOpt;
  113.     }
  114.    
  115.     //模版方法:根据多关键字批量获取集合数据
  116.     //@param keyList    入参关键字
  117.     //@param requestMap key 数据库表字段,value 字段值,该map中的字段不要与getTableFieldsMap(key)获取的字段重复
  118.     public Optional<List<BO>> listRedisStringData(List<String> keyList, Map<String, Object> requestMap) {
  119.         if (CollectionUtils.isEmpty(keyList)) {
  120.             return Optional.empty();
  121.         }
  122.         Optional<List<BO>> boListOpt = redisReadWriteManager.listRedisStringDataByBatchCache(keyList, getBOClass(), this::getRedisKey, (key) -> {
  123.             Map<String, Object> tableFieldsMap = getTableFieldsMap(key);
  124.             if (MapUtils.isNotEmpty(requestMap)) {
  125.                 tableFieldsMap.putAll(requestMap);
  126.             }
  127.             Optional<List<DO>> doOpt;
  128.             try {
  129.                 doOpt = getStringDatabase().listTableData(tableFieldsMap, queryType());
  130.             } catch (Exception e) {
  131.                 log.error("根据关键字批量获取数据异常 key={},paramMap={}", key, tableFieldsMap, e);
  132.                 return Optional.empty();
  133.             }
  134.             if (!doOpt.isPresent()) {
  135.                 return Optional.empty();
  136.             }
  137.             List<BO> boList = convertDO2BO(doOpt.get());
  138.             if (CollectionUtils.isEmpty(boList)) {
  139.                 return Optional.empty();
  140.             }
  141.             return Optional.of(boList);
  142.         });
  143.         return boListOpt;
  144.     }
  145.    
  146.     //模版方法:刷新缓存—根据主表ID集合(关联表变更需要查询主表)
  147.     //@param tableName 关联表名
  148.     //@param idSet     关联表主键集合
  149.     public void flushRedisStringDataByTableAndIdSet(String tableName, Set<Long> idSet) {
  150.         Optional<Set<Long>> idSetOpt = getStringDatabase().getTableIdSetByRelationTableIdSet(tableName, idSet);
  151.         if (!idSetOpt.isPresent()) {
  152.             return;
  153.         }
  154.         flushRedisStringDataByIdSet(idSetOpt.get());
  155.     }
  156.    
  157.     //模版方法:刷新缓存—根据表变更数据ID集合
  158.     public void flushRedisStringDataByTableUpdateData() {
  159.         Optional<Set<Long>> updateIdSetOpt = getStringDatabase().getTableUpdateIdSet();
  160.         if (!updateIdSetOpt.isPresent()) {
  161.             return;
  162.         }
  163.         flushRedisStringDataByIdSet(updateIdSetOpt.get());
  164.     }
  165.    
  166.     //模版方法:刷新缓存—根据主键ID集合
  167.     //@param idSet 数据表主键ID
  168.     private void flushRedisStringDataByIdSet(Set<Long> idSet) {
  169.         //根据id集合从数据库中查询出数据
  170.         Optional<RedisStringCache<DO>> stringSourceOpt = getStringDatabase().listTableDataByIdSet(idSet, queryType());
  171.         if (!stringSourceOpt.isPresent()) {
  172.             return;
  173.         }
  174.         RedisStringCache<DO> redisStringCache = stringSourceOpt.get();
  175.         if (!CollectionUtils.isEmpty(redisStringCache.getDeleteSet())) {
  176.             //通过缓存读写组件删除缓存
  177.             redisReadWriteManager.delete(redisStringCache.getDeleteSet().stream().map(this::getRedisKey).collect(toSet()).toArray(new String[]{}));
  178.         }
  179.         if (CollectionUtils.isEmpty(redisStringCache.getAddList())) {
  180.             return;
  181.         }
  182.         List<BO> boList = convertDO2BO(redisStringCache.getAddList());
  183.         Map<String, BO> redisMap = convertBO2Map(boList);
  184.         //通过缓存读写组件写入缓存
  185.         redisReadWriteManager.batchWriteRedisString(redisMap);
  186.     }
  187.     ...
  188. }
复制代码
 
3.自研缓存框架的通用缓存读写组件与DB操作组件
(1)通用缓存读写组件
(2)数据表的DB操作组件
 
每个数据表缓存组件都会有至少两个必备组件:一个通用缓存读写组件 + 一个数据表的DB操作组件。
 
(1)通用缓存读写组件
通用缓存读写组件也包含两个必备组件:一个操作缓存的RedisCache组件 + 一个操作分布式锁的RedisLock组件。通用缓存读写组件封装了大量基础的缓存读写操作,这些基础的缓存读写操作会结合DB读库 + 缓存问题等解决方案来进行实现。
  1. //缓存读写管理
  2. @Service
  3. public class RedisReadWriteManager {
  4.     @Resource
  5.     private RedisCache redisCache;
  6.    
  7.     @Resource
  8.     private RedisLock redisLock;
  9.     ...
  10.    
  11.     //删除指定的key
  12.     public void delete(String... keys) {
  13.         Arrays.asList(keys).stream().forEach(key -> redisCache.delete(key));
  14.     }
  15.    
  16.     //批量添加string缓存
  17.     public <T> void batchWriteRedisString(Map<String, T> redisMap) {
  18.         List<Map.Entry<String, T>> list = Lists.newArrayList(redisMap.entrySet());
  19.         try {
  20.             for (List<Map.Entry<String, T>> entries : Lists.partition(list, PAGE_SIZE_100)) {
  21.                 for (Map.Entry<String, T> entry : entries) {
  22.                     redisCache.setex(true, entry.getKey(), JSON.toJSONString(entry.getValue()), RedisKeyUtils.redisKeyRandomTime(INT_EXPIRED_SEVEN_DAYS));
  23.                 }
  24.                 try {
  25.                     Thread.sleep(SLEEP_100);
  26.                 } catch (InterruptedException e) {
  27.                     e.printStackTrace();
  28.                 }
  29.             }
  30.         } catch (Exception e) {
  31.             log.error("批量添加string缓存异常 redisMap={}", redisMap, e);
  32.         }
  33.     }
  34.    
  35.     //批量获取多缓存数据
  36.     public <T> Optional<List<T>> listRedisStringDataByBatchCache(List<String> keyList, Class<T> clazz, Function<String, String> getRedisKeyFunction, Function<String, Optional<List<T>>> getDbFuction) {
  37.         try {
  38.             List<T> list = Lists.newArrayList();
  39.             List<String> pendingKeyList = keyList.stream().distinct().collect(toList());
  40.             List<String> redisKeyList = pendingKeyList.stream().map(getRedisKeyFunction).distinct().collect(toList());
  41.             List<String> cacheList = redisCache.mget(redisKeyList);
  42.             for (int i = 0; i < cacheList.size(); i++) {
  43.                 String cache = cacheList.get(i);
  44.                 //过滤无效缓存
  45.                 if (EMPTY_OBJECT_STRING.equals(cache)) {
  46.                     continue;
  47.                 }
  48.                 if (StringUtils.isNotBlank(cache)) {
  49.                     List<T> tList = JSON.parseArray(cache, clazz);
  50.                     list.addAll(tList);
  51.                     continue;
  52.                 }
  53.                 //缓存没有则读库
  54.                 Optional<List<T>> optional = listRedisStringDataByDb(pendingKeyList.get(i), getRedisKeyFunction, getDbFuction);
  55.                 if (optional.isPresent()) {
  56.                     list.addAll(optional.get());
  57.                 }
  58.             }
  59.             return CollectionUtils.isEmpty(list) ? Optional.empty() : Optional.of(list);
  60.         } catch (Exception e) {
  61.             log.error("批量获取缓存数据异常 keyList={},clazz={}", keyList, clazz, e);
  62.             throw e;
  63.         }
  64.     }
  65.    
  66.     //读取数据库表多数据赋值到Redis
  67.     public <T> Optional<List<T>> listRedisStringDataByDb(String key, Function<String, String> getRedisKeyFunction, Function<String, Optional<List<T>>> getDbFuction) {
  68.         if (StringUtils.isEmpty(key) || Objects.isNull(getDbFuction)) {
  69.             return Optional.empty();
  70.         }
  71.         try {
  72.             if (!redisLock.lock(key)) {
  73.                 return Optional.empty();
  74.             }
  75.             String redisKey = getRedisKeyFunction.apply(key);
  76.             Optional<List<T>> optional = getDbFuction.apply(key);
  77.             if (!optional.isPresent()) {
  78.                 //把空对象暂存到redis
  79.                 redisCache.setex(true, redisKey, EMPTY_OBJECT_STRING, RedisKeyUtils.redisKeyRandomTime(INT_EXPIRED_ONE_DAY, TimeUnit.HOURS, NUMBER_24));
  80.                 log.warn("发生缓存穿透 redisKey={}", redisKey);
  81.                 return optional;
  82.             }
  83.             //把表数据对象存到redis
  84.             redisCache.setex(true, redisKey, JSON.toJSONString(optional.get()), RedisKeyUtils.redisKeyRandomTime(INT_EXPIRED_SEVEN_DAYS));
  85.             log.info("表数据对象存到Redis redisKey={}, data={}", redisKey, optional.get());
  86.             return optional;
  87.         } finally {
  88.             redisLock.unlock(key);
  89.         }
  90.     }
  91.     ...
  92. }
复制代码
(2)数据表的DB操作组件
该组件主要提供对数据表数据的查询方法。
  1. @Service("productDetailStringDatabase")
  2. public class ProductDetailStringDatabase extends AbstractRedisStringDatabase<ProductDetailDO> {
  3.     public static final String SKU_ID = "skuId";
  4.     private static final String TABLE_NAME = "sku_info";
  5.    
  6.     @Resource
  7.     private ProductRepository productRepository;
  8.    
  9.     @Override
  10.     public String getTableName() {
  11.         return TABLE_NAME;
  12.     }
  13.    
  14.     @Override
  15.     public Set<String> getTableNameSet() {
  16.         return Sets.newHashSet(getTableName());
  17.     }
  18.    
  19.     @Override
  20.     public Optional<ProductDetailDO> getTableData(Map<String, Object> tableFieldsMap, String queryType) {
  21.         if (tableFieldsMap.containsKey(SKU_ID)) {
  22.             String skuId = (String) tableFieldsMap.get(SKU_ID);
  23.             ProductDetailDO productDetailDO = productRepository.queryProductDetail(skuId);
  24.             if (!Objects.isNull(productDetailDO) && DelFlagEnum.EFFECTIVE.getCode().equals(productDetailDO.getDelFlag())) {
  25.                 return Optional.of(productDetailDO);
  26.             }
  27.             return Optional.empty();
  28.         }
  29.         return Optional.empty();
  30.     }
  31.    
  32.     @Override
  33.     public Optional<List<ProductDetailDO>> listTableData(Map<String, Object> tableFieldsMap, String queryType) {
  34.         return Optional.empty();
  35.     }
  36.    
  37.     @Override
  38.     public Optional<RedisStringCache<ProductDetailDO>> listTableDataByIdSet(Set<Long> idSet, String queryType) {
  39.         RedisStringCache redisStringCache = new RedisStringCache();
  40.         List<ProductDetailDO> addList = new ArrayList<>();
  41.         for (Long skuId : idSet) {
  42.             ProductDetailDO productDetailDO = productRepository.queryProductDetail(String.valueOf(skuId));
  43.             if (!Objects.isNull(productDetailDO)) {
  44.                 addList.add(productDetailDO);
  45.             }
  46.         }
  47.         redisStringCache.setAddList(addList);
  48.         return Optional.of(redisStringCache);
  49.     }
  50.    
  51.     @Override
  52.     public Optional<RedisStringCache<ProductDetailDO>> listTableDataByIdSet(List<Long> idSet, String queryType) {
  53.         Long skuId = idSet.get(0);
  54.         ProductDetailDO productDetailDO = productRepository.queryProductDetail(String.valueOf(skuId));
  55.         RedisStringCache redisStringCache = new RedisStringCache();
  56.         redisStringCache.setAddList(Arrays.asList(productDetailDO));
  57.         return Optional.of(redisStringCache);
  58.     }
  59. }
复制代码
 

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册