Redis( stringRedisTemplate)添加缓存数据

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: 在redis中添加缓存数据大致思路:1,从redis中获取数据,如果存在,直接返回客户端2,不存在,查询数据库,并写入redis缓存3,如果从数据库查询为空,返回错误信息4,写入redis缓存并返回数据

通过String类型添加商品数据

string思路:如果缓存中存在,需要把获取到的JSON数据转换为实体类

                   如果缓存不存在,则需要把查询到的数据转为JSON写入redis

1. public Result queryById(Long id) {
2. String shopKey = CACHE_SHOP_KEY + id;
3. //从redis中获取缓存
4. String shopJson = stringRedisTemplate.opsForValue().get(shopKey);
5. //判断是否存在
6. //如果存在直接返回查询结果
7. if (!StringUtils.isEmpty(shopJson)){
8. Shop shop = JSONUtil.toBean(shopJson, Shop.class);
9. return Result.ok(shop);
10.         }
11. //如果不存在,查询数据库
12. Shop shop = this.getById(id);
13. 
14. //如果数据库中也不存在,返回错误信息
15. if (shop==null){
16. return Result.fail("商品不存在");
17.         }
18. //将对象转为json存储
19. String shoptoJson = JSONUtil.toJsonStr(shop);
20. //如果存在写入redis缓存并返回查询信息
21.         stringRedisTemplate.opsForValue().set(shopKey,shoptoJson);
22. return Result.ok(shop);
23.     }

通过hash方式进行存储

hssh思路:如果缓存中存在,需要通过hutool工具类将map转换为对象并返回客户端

                 如果缓存中不存在,查询数据库,并将实体类转为map写入缓存,因为本文使用的是StringRedisTemple所以需要将实体类中非String类型字段转换为String类型进行存储,最终返回数据到客户端

1. public Result queryById(Long id) {
2. /**
3.          * 添加商户缓存,采用map形式
4.          */
5. String shopKey = CACHE_SHOP_KEY + id;
6. //如果缓存中有数据,直接返回客户端
7.         Map<Object, Object> shopMap = stringRedisTemplate.opsForHash().entries(shopKey);
8. if (shopMap!=null && shopMap.size()>0){
9. //将map转换为对象
10. Shop shop = BeanUtil.fillBeanWithMap(shopMap, new Shop(), false);
11. return Result.ok(shop);
12.         }
13. //如果缓存中没有数据,查询数据库并写入redis缓存
14. Shop shop = this.getById(id);
15. if (shop==null){
16. return Result.fail("不存在此商品");
17.         }
18. //将对象中的非String类型转为String类型
19.         Map<String, Object> shopMaps = BeanUtil.beanToMap(shop, new HashMap<>(),
20.                 CopyOptions.create().
21.                         setIgnoreNullValue(true).setFieldValueEditor((filedName, filedValue) -> {
22. if (filedValue == null) {
23.                                 filedValue = "0";
24.                             } else {
25.                                 filedValue = filedValue + "";
26.                             }
27. return filedValue;
28.                         }));
29. 
30.         stringRedisTemplate.opsForHash().putAll(shopKey,shopMaps);
31. return Result.ok(shop);
32.     }

通过List进行存储

通过List存储思路:通过list获取商品类型,判断是否命中缓存,如果命中缓存,遍历从Redis中获取到的集合并遍历设置到泛型为当前实体类对象的类型的集合,

                             如果缓存未命中,从数据库中查询数据,并获取到这个集合,遍历这个集合,并转换为JSON类型添加到一个泛型为String的集合,通过调用rightPushAll来完成redis的写入

1. public Result queryTypeList() {
2. //1.在redis中间查询,通过list获取商品类型
3.         List<String> shopTypeList = new ArrayList<>();
4.         shopTypeList = stringRedisTemplate.opsForList().range(CACHE_SHOP_TYPE_KEY,0,-1);
5. //2.判断是否缓存中了
6. //3.中了返回
7. if (!shopTypeList.isEmpty()){
8.             List<ShopType> typeList = new ArrayList<>();
9. for (String str:shopTypeList) {
10. ShopType shopType = JSONUtil.toBean(str, ShopType.class);
11.                 typeList.add(shopType);
12.             }
13. return Result.ok(typeList);
14.         }
15. //不存在,从数据库中查询
16.         List<ShopType> shopTypes = this.query().orderByAsc("sort").list();
17. if (shopTypes==null && shopTypes.size()>0){
18. return Result.fail("没有商品类型信息");
19.         }
20. //存在添加redis缓存
21. for(ShopType shopType : shopTypes){
22. String s = JSONUtil.toJsonStr(shopType);
23.             shopTypeList.add(s);
24.         }
25.         stringRedisTemplate.opsForList().rightPushAll(CACHE_SHOP_TYPE_KEY,shopTypeList);
26. return Result.ok(shopTypes);
27.     }

通过set进行存储

1. public List<Content> getLike() {
2. String key = "carousel:like";
3.         List<String> stringList = new ArrayList<>();
4.         stringList = stringRedisTemplate.opsForSet().randomMembers(key, 6);
5. if (!stringList.isEmpty()){
6.             List<Content> contents = new ArrayList<>();
7. for (String s : stringList) {
8. Content content = JSONUtil.toBean(s, Content.class);
9.                 contents.add(content);
10.             }
11. return contents;
12.         }
13. //查询数据库
14. //未命中查询数据库
15.         List<Content> contents = baseMapper.selectList(new QueryWrapper<Content>().eq("category_id",3));
16. 
17. //添加redis并返回6条数据
18.         List<Content> contentList = new ArrayList<>();
19. for (int i = 0; i < contents.size(); i++) {
20. String s = JSONUtil.toJsonStr(contents.get(i));
21.             stringRedisTemplate.opsForSet().add(key,s);
22. if (i<6){
23.                 contentList.add(contents.get(i));
24.             }
25.         }
26. return contentList;
27.     }

通过zset进行存储

1. public List<Movie> getpopularList() {
2.         List<Movie> movies = new ArrayList<>();
3.         Set<String> set = stringRedisTemplate.opsForZSet().reverseRange(MOVIE_POPULAR,0,-1);
4. //判断是否命中缓存
5. if (set != null && set.size()>0){
6.               List<String> zsetStrings = new ArrayList<>(set);
7. //命中返回
8. for (String zsetString : zsetStrings) {
9.                  movies.add(JSONUtil.toBean(zsetString,Movie.class));
10.               }
11. return movies;
12.           }
13.         movies = baseMapper.selectList(new QueryWrapper<Movie>().orderByDesc("score").last("limit 0,6"));
14. //写入redis数据库
15. for (Movie movie : movies) {
16. String s = JSONUtil.toJsonStr(movie);
17.               stringRedisTemplate.opsForZSet().add(MOVIE_POPULAR,s,movie.getScore());
18.           }
19. return movies;
20.     }
相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
2天前
|
缓存 监控 NoSQL
redis 缓存穿透 击穿 雪崩 的原因及解决方法
redis 缓存穿透 击穿 雪崩 的原因及解决方法
|
3天前
|
存储 缓存 NoSQL
Redis 缓存失效策略及其应用场景
Redis 缓存失效策略及其应用场景
16 1
|
5天前
|
缓存 NoSQL 关系型数据库
redis(缓存)
redis(缓存)
13 0
|
7天前
|
存储 缓存 监控
利用Redis构建高性能的缓存系统
在现代Web应用中,性能优化是提升用户体验和响应速度的关键。Redis作为一款开源的内存数据结构存储系统,因其出色的性能、丰富的数据结构和灵活的使用方式,成为了构建高性能缓存系统的首选工具。本文将探讨Redis在缓存系统中的应用,分析其优势,并通过实例展示如何结合Redis构建高效、可靠的缓存系统,以应对高并发、大数据量等挑战。
|
11天前
|
缓存 NoSQL Redis
【后端面经】【缓存】36|Redis 单线程:为什么 Redis 用单线程而 Memcached 用多线程?-- Redis多线程
【5月更文挑战第21天】Redis启用多线程后,主线程负责接收事件和命令执行,IO线程处理读写数据。请求处理流程中,主线程接收客户端请求,IO线程读取并解析命令,主线程执行后写回响应。业界普遍认为,除非必要,否则不建议启用多线程模式,因单线程性能已能满足多数需求。公司实际场景中,启用多线程使QPS提升约50%,或选择使用Redis Cluster以提升性能和可用性。
20 0
|
12天前
|
NoSQL Redis 数据库
【后端面经】【缓存】36|Redis 单线程:为什么 Redis 用单线程而 Memcached 用多线程?-- Memcache + Redis 多线程
【5月更文挑战第20天】Redis采用单线程模式以避免上下文切换和资源竞争,简化调试,且其性能瓶颈在于网络IO和内存,而非多线程。相比之下,Memcache使用多线程能更好地利用多核CPU,但伴随上下文切换和锁管理的开销。尽管Redis单线程性能不俗,6.0版本引入多线程以提升高并发下的IO处理能力。启用多线程后,Redis结合Reactor和epoll实现并发处理,提高系统性能。
33 0
|
12天前
|
存储 NoSQL 容灾
怎样保证Redis 保证数据不丢失?
Redis 数据不丢失主要靠持久化(RDB、AOF、混合)和集群运行(主从同步、哨兵、Cluster)。RDB是快照,恢复速度快但可能丢失部分数据;AOF记录所有命令,实时性好但写性能较低;混合持久化结合两者优点。集群通过多服务器分布数据,提高可用性和数据安全性。
|
13天前
|
缓存 NoSQL 中间件
【后端面经】【缓存】36|Redis 单线程:为什么 Redis 用单线程而 Memcached 用多线程?epoll、poll和select + Reactor模式
【5月更文挑战第19天】`epoll`、`poll`和`select`是Linux下多路复用IO的三种方式。`select`需要主动调用检查文件描述符,而`epoll`能实现回调,即使不调用`epoll_wait`也能处理就绪事件。`poll`与`select`类似,但支持更多文件描述符。面试时,重点讲解`epoll`的高效性和`Reactor`模式,该模式包括一个分发器和多个处理器,用于处理连接和读写事件。Redis采用单线程模型结合`epoll`的Reactor模式,确保高性能。在Redis 6.0后引入多线程,但基本原理保持不变。
30 2
|
13天前
|
消息中间件 缓存 监控
中间件如果缓存中存在所需的数据(缓存命中)
【5月更文挑战第12天】中间件如果缓存中存在所需的数据(缓存命中)
34 3
|
13天前
|
存储 缓存 监控