黑馬程序員Redis入門到實戰(zhàn)教程,深度透析redis底層原理+redis分布式

P37作業(yè)(解決緩存穿透版):
@Override public Result queryShopType() { String key = CACHE_SHOP_TYPE_KEY; // 1.查詢redis緩存 List<String> typeJson = stringRedisTemplate.opsForList().range(key, 0, -1); // 2.判斷是否命中 if (CollectionUtil.isNotEmpty(typeJson)) { // 2.0 如果為空對象(防止緩存穿透時存入的空對象) if (StrUtil.isBlank(typeJson.get(0))) { return Result.fail("商品分類信息為空!"); } // 2.1 命中則轉換List<String> -> List<ShopType> 并返回、 List<ShopType> typeList = new ArrayList<>(); for (String jsonString : typeJson) { ShopType shopType = JSONUtil.toBean(jsonString, ShopType.class); typeList.add(shopType); } return Result.ok(typeList); } // 3. 未命中,查詢數(shù)據(jù)庫 List<ShopType> typeList = query().orderByAsc("sort").list(); // 3.1 數(shù)據(jù)庫中不存在 if (CollectionUtil.isEmpty(typeList)) { // 添加空對象到redis,解決緩存穿透 stringRedisTemplate.opsForList().rightPushAll(key, CollectionUtil.newArrayList("")); stringRedisTemplate.expire(key,CACHE_NULL_TTL,TimeUnit.MINUTES); // 返回錯誤 return Result.fail("商品分類信息為空!"); } // 3.2 數(shù)據(jù)庫中存在,轉換List<ShopType> -> List<String> 類型 List<String> shopTypeList = new ArrayList<>(); for (ShopType shopType : typeList) { String jsonStr = JSONUtil.toJsonStr(shopType); shopTypeList.add(jsonStr); } // 4.寫入redis緩存, 有順序只能RPUSH stringRedisTemplate.opsForList().rightPushAll(key, shopTypeList); // 5. 返回 return Result.ok(typeList); }
標簽: