Redis的缓存问题(一)添加redis缓存与扩展

编程入门 行业动态 更新时间:2024-10-15 06:15:26

Redis的<a href=https://www.elefans.com/category/jswz/34/1771061.html style=缓存问题(一)添加redis缓存与扩展"/>

Redis的缓存问题(一)添加redis缓存与扩展

什么是缓存?

缓存的作用与成本

作用

成本

如何添加redis缓存?

缓存作用模型

需求分析

代码实现

ShopController

IShopService 业务层接口

ShopServiceImpl 业务层实现类

扩展功能实现

视频地址如下 

代码详情

完整代码,需要自取(完整无套路)


什么是缓存?

缓存就是数据交换缓冲区(称作Cache),是存贮数据的临时地方,一般读写性能较高

缓存的作用与成本

作用

  •  当请求进入Tomcat以后,以前是查询数据库,而数据库本身是存在磁盘中的,查询需要进行IO操作,耗时,会给数据库造成压力;但是当我们有了缓存,请求进入Tomcat以后,直接进入Redis,查到后将结果返回给前端,就减轻了后端的负载。
  • 基于内存,所以读写快!

成本

  • 同一份数据在Redis与数据库中是要保证一致的!
  • 代码会更加复杂。
  • 为了高可用、防止雪崩,可能需要搭建集群,需要运维成本。

如何添加redis缓存?

缓存作用模型

先查询Redis,如果命中,直接将数据取出;反之未命中,则查询MySQL数据库,若有数据返回客户端,并且将其写入Redis缓存中。

需求分析

查询导航栏,点击后查看

我们需要的就是给API添加缓存 

代码实现

ShopController

之前是直接访问数据库,如下:

@GetMapping("/{id}")
public Result queryShopById(@PathVariable("id") Long id) {return Result.ok(shopService.getById(id));
}

但是这里需要用到redis,步骤比较多,所以我们在Controller层需要调用Service层去实现该逻辑。

@GetMapping("/{id}")
public Result queryShopById(@PathVariable("id") Long id) {//return Result.ok(shopService.getById(id));return shopService.queryById(id);
}

IShopService 业务层接口

public interface IShopService extends IService<Shop> {Result queryById(Long id);
}

ShopServiceImpl 业务层实现类

@Service
public class ShopServiceImpl extends ServiceImpl<ShopMapper, Shop> implements IShopService {@Resourceprivate StringRedisTemplate stringRedisTemplate;@Overridepublic Result queryById(Long id) {// 1.从redis查询商铺缓存String key = CACHE_SHOP_KEY + id;String shopJson = stringRedisTemplate.opsForValue().get(key);// 2.判断是否存在if (StrUtil.isNotBlank(shopJson)) {// 3.存在,直接返回Shop shop = JSONUtil.toBean(shopJson, Shop.class);System.out.println("Redis");return Result.ok(shop);}// 4.不存在,根据id查询数据库Shop shop = getById(id);// 5.不存在,返回错误if (shop == null) {return Result.fail("店铺不存在!");}// 6.存在,写入Redis// 把shop转换成为JSON形式写入RedisSystem.out.println("MySQL");stringRedisTemplate.opsForValue().set(key, JSONUtil.toJsonStr(shop));return Result.ok(shop);}
}

如下所示: 这些数据一旦被访问就会被写入Redis中。

此处,redis的存储结构我们采用的是string的结构(当然使用Hash也是可以的) 

我们可以看看打印控制台

显然第一次查询执行了SQL,第二次就是直接从Redis去数据了!

Preparing: SELECT id,name,type_id,images,area,address,x,y,avg_price,sold,comments,score,open_hours,create_time,update_time FROM tb_shop WHERE id=?

日志总览 

2022-07-06 14:12:00.497 DEBUG 7464 --- [nio-8081-exec-4] c.h.m.VoucherMapper.queryVoucherOfShop   : ==>  Preparing: SELECT v.`id`, v.`shop_id`, v.`title`, v.`sub_title`, v.`rules`, v.`pay_value`, v.`actual_value`, v.`type`, sv.`stock` , sv.begin_time , sv.end_time FROM tb_voucher v LEFT JOIN tb_seckill_voucher sv ON v.id = sv.voucher_id WHERE v.shop_id = ? AND v.status = 1
2022-07-06 14:12:00.498 DEBUG 7464 --- [nio-8081-exec-4] c.h.m.VoucherMapper.queryVoucherOfShop   : ==> Parameters: 1(Long)
2022-07-06 14:12:00.500 DEBUG 7464 --- [nio-8081-exec-4] c.h.m.VoucherMapper.queryVoucherOfShop   : <==      Total: 1
2022-07-06 14:12:00.500 DEBUG 7464 --- [nio-8081-exec-2] com.hmdp.mapper.ShopMapper.selectById    : ==>  Preparing: SELECT id,name,type_id,images,area,address,x,y,avg_price,sold,comments,score,open_hours,create_time,update_time FROM tb_shop WHERE id=?
2022-07-06 14:12:00.500 DEBUG 7464 --- [nio-8081-exec-2] com.hmdp.mapper.ShopMapper.selectById    : ==> Parameters: 1(Long)
2022-07-06 14:12:00.503 DEBUG 7464 --- [nio-8081-exec-2] com.hmdp.mapper.ShopMapper.selectById    : <==      Total: 1
MySQL
2022-07-06 14:12:05.146 DEBUG 7464 --- [nio-8081-exec-3] c.h.m.VoucherMapper.queryVoucherOfShop   : ==>  Preparing: SELECT v.`id`, v.`shop_id`, v.`title`, v.`sub_title`, v.`rules`, v.`pay_value`, v.`actual_value`, v.`type`, sv.`stock` , sv.begin_time , sv.end_time FROM tb_voucher v LEFT JOIN tb_seckill_voucher sv ON v.id = sv.voucher_id WHERE v.shop_id = ? AND v.status = 1
2022-07-06 14:12:05.146 DEBUG 7464 --- [nio-8081-exec-3] c.h.m.VoucherMapper.queryVoucherOfShop   : ==> Parameters: 1(Long)
2022-07-06 14:12:05.148 DEBUG 7464 --- [nio-8081-exec-3] c.h.m.VoucherMapper.queryVoucherOfShop   : <==      Total: 1
Redis

扩展功能实现

如下这些logo一般是长期存在的,每次登入我们都要重新加载,所以这里将其缓存在Redis中,来提高网页的效率问题。

在黑马程序员的视频中,P37的视频留了一道练习题,我们在这里将其实现以下:

视频地址如下 

黑马程序员Redis入门到实战教程,全面透析redis底层原理+redis分布式锁+企业解决方案+redis实战_哔哩哔哩_bilibili=37&vd_source=470cf4bd5833d6feeb5c5aaefc5e3465

代码详情

ShopTypeController

调用Service层,在Service中去做具体的实现 

@RestController
@RequestMapping("/shop-type")
public class ShopTypeController {@Resourceprivate IShopTypeService typeService;@GetMapping("list")public Result queryTypeList() {
//        List<ShopType> typeList = typeService
//                .query().orderByAsc("sort").list();
//        return Result.ok(typeList);return typeService.getByIconList();}
}

ShopTypeServiceImpl 

@Service
public class ShopTypeServiceImpl extends ServiceImpl<ShopTypeMapper, ShopType> implements IShopTypeService {@Resourceprivate StringRedisTemplate stringRedisTemplate;@Overridepublic Result getByIconList() {// 1.在redis中间查询String key = CACHE_SHOP_TYPE_KEY;List<String> shopTypeList = new ArrayList<>();// range()中的 -1 表示最后一位// shopTypeList中存放的数据是[{...},{...},{...}...] 一个列表中有一个个json对象shopTypeList = stringRedisTemplate.opsForList().range(key,0,-1);// 2.判断是否缓存中了// 3.中了返回 (判断redis不空)if(!shopTypeList.isEmpty()) {List<ShopType> typeList = new ArrayList<>();for (String s : shopTypeList) {ShopType shopType = JSONUtil.toBean(s, ShopType.class);// shopType 是一个对象typeList.add(shopType);}return Result.ok(typeList);}// 4.redis未命中数据,从数据库中获取,根据ShopType对象的sort属性排序后存入typeListList<ShopType> typeList = query().orderByAsc("sort").list();// 5.数据库中如果不存在直接返回错误if(typeList.isEmpty()){return Result.fail("不存在分类");}for(ShopType shopType : typeList){String s = JSONUtil.toJsonStr(shopType);shopTypeList.add(s);}// 6.存在直接添加进缓存stringRedisTemplate.opsForList().rightPushAll(key, shopTypeList);return Result.ok(typeList);}
}

注意点: 

这里有一些东西需要解释一下,stringRedisTemplate.opsForList().range(key,0,-1); 中的range的 -1 代表的是最后一个的意思,即这些logo的数量为10个所以range(key,0,10);是一个意思。

代码实现思路与上面的样例类似,只是需要注意的是返回的 typeList 是一个 List 列表。

完整代码,需要自取(完整无套路)

链接: 
提取码:l2hh 
--来自百度网盘超级会员V4的分享

更多推荐

Redis的缓存问题(一)添加redis缓存与扩展

本文发布于:2024-03-07 09:37:24,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1717467.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:缓存   Redis   redis

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!