目录
一、添加redis缓存的主要逻辑
在未添加缓存时,前端向后端发起查询请求时,后端收到请求就直接查数据库,它的速度如下:
其实速度也不慢,那是因为我的数据库里面没有太多数据,所以查起来速度还是特别快的,但随着我们的数据库数据量逐渐增大,如果没有缓存的话,那查询速度会越来越慢。
添加redis缓存的逻辑也不难,总结下来也就是以下这几点:
1.后端查询时,先查redis缓存,redis缓存中有数据直接返回,没有数据再去查数据库
2.查数据库时,没有对应数据则向前端发出错误信息,有数据则向前端发送数据并将数据写入redis缓存中
流程图如下所示:
二、代码
java
@Service
public class ShopServiceImpl extends ServiceImpl<ShopMapper, Shop> implements IShopService {
@Autowired
private StringRedisTemplate stringRedisTemplate;
/**
* 根据id查询店铺信息
* @param id
* @return
*/
@Override
public Result queryById(Long id) {
String key = RedisConstants.CACHE_SHOP_KEY + id;
//1.从redis中查询商铺缓存信息
String shopJson = stringRedisTemplate.opsForValue().get(key);
//2、判断是否存在
if (StrUtil.isNotBlank(shopJson)) {
//3、存在,直接返回
Shop shop = JSONUtil.toBean(shopJson, Shop.class);
return Result.ok(shop);
}
//4、不存在,根据id查询数据库
Shop shop = getById(id);
//5、判断数据库中是否有数据
if (shop == null) {
//6、没有,返回错误
return Result.fail("店铺不存在");
}
//7、有数据,返回,并将数据写入redis
String jsonStr = JSONUtil.toJsonStr(shop);
stringRedisTemplate.opsForValue().set(key,jsonStr);
//8、返回结果
return Result.ok(shop);
}
}
三、结果
当第一次执行时,redis中是没有数据的,执行过后就会将对应数据写入redis中
下一次的查询时速度就会快上不少
如果数据库中的数据更多的话,效果会更加明显
四、缓存更新策略
既然我们已经对查询业务增加了缓存,那当数据库的数据和缓存数据不一样的时候,我们如何去解决它们之间的一致性问题呢?
其实解决方案十分简单:
当数据库的数据发生变更时,例如增加、删除、修改等操作,我们先去操作数据库再去删除缓存。
为什么选择删除缓存而不选择更新缓存呢?
如果选择更新缓存很可能会出现多次无效的写操作,比如:我更新了十次数据库之后才有一次查询操作,这时候缓存也是随之更新了十次。那如果我在他第一次更新数据库的时候就选择删除缓存,那么我就省去了这些更新缓存的无效写操作,性能上肯定是提高了不少。因此我们会选择删除缓存而不是更新缓存。
为什么要选择先操作数据库而不是先操作缓存呢?
因为数据库是基于磁盘的,缓存是基于内存的,操作数据库的耗时往往会比操作缓存的耗时大上不少。因此如果先删缓存再更新数据库,那就会出现在更新数据库的过程中(时间比较长)被其他查询缓存的操作乘虚而入,这时候缓存为空会从数据库中拿数据填入缓存,这时候就会出现数据不一致的问题。因此我们会选择先操作数据库再操作缓存。
因此我们还要给上面写的代码进行补全,在对数据进行修改的时候要进行以下的逻辑:
1.更新数据库
2.删除缓存
五、代码
java
@Override
@Transactional
public Result update(Shop shop) {
Long id = shop.getId();
if (id == null) {
return Result.fail("店铺id不能为空");
}
//1.更新数据库
updateById(shop);
//2.删除缓存
stringRedisTemplate.delete(RedisConstants.CACHE_SHOP_KEY + id);
//3.返回结果
return Result.ok();
}