问题引入
在重新编写更新浏览量逻辑的时候,也就是给这个更新博客浏览量也给予一个接口,前端在访问文章详情的时候,顺带着访问了这个接口,就更新了Redis中的浏览量数据,这里我们最好不是自己在serviceImpl中直接使用原始的redisTemplate去更新浏览量了,而应该在redisCacle中封装一个方法,专门用于增加redis中hash结构的value值,也就是这个:
/**
* 为Redis中value对应的map增加value
* @param key 键值
* @param hKey value-map对应的键值
* @param v value-map 对应的value值
*/
public void incrementCacheMapValue(String key,String hKey,int v){
redisTemplate.boundHashOps(key).increment(hKey, v);
}
下面是控制器中的代码:
@Override
public ResponseResult updateViewCount(Long id) {
//每次为阅读量增加1
redisCache.incrementCacheMapValue("id-viewcount-map",id.toString(),1);
return ResponseResult.okResult();
}
没想很多,就赶紧测试了,结果在前端一点文章详情,控制台就报错了,报错信息如下:
报错信息大概说:hash结构中value类型不是一个Integer类型。
分析问题
后来我通过Redis的可视化界面,查看value的类型,确实不是Intetger类型,而是字符串类型,如下图所示:
而原来我以前那种逻辑是这样的:
//增加Redis中的数据
Long count = (Long)redisCache.getCacheMapValue("id-viewcount-map", articleId.toString());
Map<String, Object> map = redisCache.getCacheMap("id-viewcount-map");
map.put(articleId.toString(),++count);
redisCache.setCacheMap("id-viewcount-map",map);
先获取redis中的count,然后让count自增1,然后重新封装成map,然后在重新存入redis即可,这样没有问题,因为我没有直接对redis中的value进行数值运算,而我之后的那种方法其实是直接对Redis中的数据进行运算的,因为是String类型的,当然也就不能运算了,当然也就报错了。
这里我们发现一个问题,那就是为什么在这里:
存入Redis中hash的value类型是Long类型的,为啥在可视化工具那里却变成了String类型的,其实是因为Redis中hash结构的value类型只能是String类型的,如果存入了其它类型,又不是Integer类型的,那么就会转为String,如果是Interger类型的,那么会进行处理,变成Intetger类型,也就可以直接运算了。所以如果我们想让value类型直接就是Integer类型,直接可以参与运算,就直接在存入Redis中hash的value类型搞成Intetget类型就行了。
解决问题
直接在存入Redis中hash的value类型搞成Intetget类型,如图:
总结
这次出错的原因在于Redis那块知识点掌握不牢,不清楚redis中hash结构的value类型,确实是因为学Redis已经学过,好久了都忘记好多了,连Redis的基本的几种数据类型都忘了,后面又回顾了一遍,Redis一共有5中数据类型,分别是string、list、set、zset、hash,这都是指的Redis键值对中value的类型,其中注意存string时,如果是数字字符串,那么便可以直接参与计算,hash结构的value类型存的是string类型,如果不是string类型,也会转为string类型,set可以去重,zset就是可以指定排序规则的键