public List<ShopType> queryTypeList() {
String key = CACHE_SHOPTYPE_KEY;
String typeListJson = stringRedisTemplate.opsForValue().get(key);
if(StrUtil.isNotBlank(typeListJson)){
return JSONUtil.toList(typeListJson, ShopType.class);//修改点1 return JSONUtil.toBean(typeListJson, List.class);这样写返回的不是一个ShopType类型的数组,而是List<JSONObject>
}
List<ShopType> shopTypeList = this.query().orderByAsc("sort").list();
//处理空值缓存(防止缓存穿透)
if(shopTypeList == null || shopTypeList.isEmpty()){ //修改点2
stringRedisTemplate.opsForValue().set(key,"",CACHE_SHOPTYPE_TTL,TimeUnit.MINUTES);
}
else {
stringRedisTemplate.opsForValue().set(key, JSONUtil.toJsonStr(shopTypeList), CACHE_SHOPTYPE_TTL, TimeUnit.MINUTES);
}
return shopTypeList;
}
缓存穿透
缓存穿透是指恶意或异常的请求频繁访问缓存和数据库中都不存在的数据,导致请求直接穿透缓存层,全部打到数据库,造成数据库压力过大甚至宕机。 当数据库返回空结果时,将空字符串缓存到redis,后续就不会重复访问数据库,保护数据库。 空值缓存的过期时间应较短(如2分钟),避免长期存储无效数据。
所谓穿透二字可以理解为:请求绕过缓存层的保护机制,直接访问底层存储。