(一) 什么是缓存


(二)添加商户缓存


控制层
/**
* 根据id查询商铺信息
* @param id 商铺id
* @return 商铺详情数据
*/
@GetMapping("/{id}")
public Result queryShopById(@PathVariable("id") Long id) {
return shopService.queryById(id);
}
service层
public interface IShopService extends IService<Shop> {
Result queryById(Long id);
}
@Service
public class ShopServiceImpl extends ServiceImpl<ShopMapper, Shop> implements IShopService{
@Resource
private StringRedisTemplate stringRedisTemplate;
@Override
public Result queryById(Long id) {
String key = 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.不存在,查询数据库
Shop shop = getById(id);
if(shop == null){
return Result.fail("店铺不存在:!");
}
// 5.存在, 存入redis
stringRedisTemplate.opsForValue().set(key,JSONUtil.toJsonStr(shop));
return Result.ok(shop);
}
}
测试效果:

(三)缓存练习题分析

自行实现即可,不难
(四)缓存更新策略



先删除缓存,在操作数据库的正常情况(缓存 数据库 一开始都是10)

产生不一致情况:

先操作数据库,在删除缓存的正常情况:

产生不一致情况:

方案二先操作数据库,在删除缓存比方案一概率更低,因为需要线程1恰好查询缓存的时候缓存是失效的,同时在准备写入缓存的很短的时间需要有线程二进来更新数据库,删除缓存,需要这两个条件同时成立。

(五)实现商铺缓存与数据库的双写一致

这里更新接口字段需要去掉updatetime和createtime,因为会报错,后续在找办法解决,子需要自定义配置时间就行,多个配置类。
org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: raw timestamp (1642066339000) not allowed for java.time.LocalDateTime: need additional information such as an offset or time-zone (see class Javadocs); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: raw timestamp (1642066339000) not allowed for java.time.LocalDateTime: need additional information such as an offset or time-zone (see class Javadocs)
at [Source: (PushbackInputStream); line: 7, column: 19] (through reference chain: com.hmdp.entity.Shop[“updateTime”])

当执行更新店铺时,会更新数据库,在删除缓存

当再次查询时数据库时,会自动更新缓存

修改代码如下,添加缓存时候设置过期时间,然后在更新数据库时删除缓存。
@Override
public Result queryById(Long id) {
String key = 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.不存在,查询数据库
Shop shop = getById(id);
if(shop == null){
return Result.fail("店铺不存在:!");
}
// 5.存在, 存入redis
stringRedisTemplate.opsForValue().set(key,JSONUtil.toJsonStr(shop),CACHE_SHOP_TTL, TimeUnit.MINUTES);
return Result.ok(shop);
}
@Override
@Transactional
public Result update(Shop shop) {
Long id = shop.getId();
if(id == null){

最低0.47元/天 解锁文章
543

被折叠的 条评论
为什么被折叠?



