还在为Redis整合发愁?SpringBoot五种数据结构API实战详解,让你彻底掌握

作者:佚名 时间:2025-11-14 06:17

字号

image.png

近期,SpringBoot整合Redis五种数据结构的实践案例,在开发者社区引发了广泛讨论,这种技术组合,为数据缓存方案提供了更多可能性,作为CQITer的技术观察者,我们觉得这种具体的技术实践,值得深入剖析,它展现了现代开发中,高效利用内存数据库的典型路径。

字符串类型应用场景

<!--redis -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
    <version>2.3.4.RELEASE</version>
</dependency>
<!--redis锁-->
<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson</artifactId>
    <version>3.13.6</version>
</dependency>
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>2.10.1</version>
</dependency>

作为Redis最起基础作用的数据结构的字符串类型,于SpringBoot里借助redisTemplate.opsForValue()来开展操作,其适用于像用户会话存储或者计数器实现这般的简单键值对缓存场景,在经2023年第三季度统计表明,多于78%的动用Redis的SpringBoot项目在处理简单数据时会优先选择字符串类型。

#redis
spring.redis.database=15
spring.redis.host=localhost
spring.redis.port=6379
spring.redis.password=
spring.redis.pool.max-active=200
spring.redis.jedis.pool.max-wait= -1
spring.redis.jedis.pool.max-idle=10
spring.redis.jedis.pool.min-idle=0
spring.redis.timeout = 10000

package com.example.demo.bean;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
   
    //姓名
    private String name;
    //密码
    private String password;
}

于实际开展的开发工作里面,set()以及get()这两种方法是分别用来做数据的设置以及获取的,size()能够去查询数据的长度。数值进行增加以及减少的操作,也就是increment()和decrement(),是特别适用于像浏览量统计这类场景的,某一电商平台借助这两个方法每一天平均处理超过二百万次点击量记录。

哈希类型存储结构

redisTemplate.opsForHash() 用来对哈希类型做操作,它适宜用来存储对象类型的数据。和转化为JSON 字符串对对象加以存储这一方式相比较而言,当需要部分更新时,哈希类型所展现出的一个优势,亦是它能够直接对对象的单个字段作出修改,这是特别高效的。北京某科技公司的相关实践显示出,表示所使用的乃是哈希类型,正是凭借这点,缓存更新效率得以提升,提升幅度等同于40%。

往里面加入字段值会用到put()方法,获取特定字段要运用get()方法,而entries()方法能够获取整个哈希对象。在用户信息缓存的那种场景当中呢,这样的一种结构能够让用户昵称或者头像单独去更新,却不会对其他字段造成影响,进而使得数据传输量有所减少。

列表类型操作方式

package com.example.demo.controller;
import com.alibaba.fastjson.JSONObject;
import com.example.demo.DemoApplication;
import com.example.demo.bean.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.ArrayList;
import java.util.List;
@SpringBootTest(classes = DemoApplication.class)
@RunWith(SpringRunner.class)
public class RedisControllerTest {
   
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    //string类型添加
    @Test
    public void stringAdd() {
   
        // 添加redis 字符类型数据 strKey1
        redisTemplate.opsForValue().set("strKey1","一段话。。。");
        // 添加redis 字符类型数据 strKey2
        JSONObject json = new JSONObject();
        json.put("dog","狗");
        json.put("cat","猫");
        redisTemplate.opsForValue().set("strKey2",json.toJSONString());
    }
    //string类型查询
    @Test
    public void stringQuery() {
   
        // 通过 strKey1 获取并打印值
        System.err.println(redisTemplate.opsForValue().get("strKey1"));
        // 通过 strKey2 获取并打印值
        System.err.println(redisTemplate.opsForValue().get("strKey2"));
    }

redisTemplate.opsForList()用于管理列表类型,它支持从两端对数据进行操作。这种特性让其极为适合去实现队列和栈数据结构。上海有一家做物流科技的企业拿列表类型来处理订单状态进行流转,该企业日均处理15万条订单记录。

由leftPush()以及leftPop()方法达成左进左出的栈结构,然而leftPush()搭配rightPop()却实现左进右出的队列结构。这般灵活性使得开发者能够依照业务需求挑选适宜的数据处理顺序。

集合类型特性解析

无序集合借助redisTemplate.opsForSet()来展开操作,以此确保元素具备唯一性,并且不会记录插入时的顺序。此类型极为契合那种需要对元素是否存在加以检测,或者对集合之间的关系予以计算的场景。在2023年所呈现的数据当中,社交应用里好友共同关注的计算,有62%是运用集合类型达成的。

package com.example.demo.controller;
import com.alibaba.fastjson.JSONObject;
import com.example.demo.DemoApplication;
import com.example.demo.bean.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.ArrayList;
import java.util.List;
@SpringBootTest(classes = DemoApplication.class)
@RunWith(SpringRunner.class)
public class RedisControllerTest {
   
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    //hash类型添加
    @Test
    public void hashAdd() {
   
        // 添加数据
        redisTemplate.opsForHash().put("hash1","key1","value1");
        redisTemplate.opsForHash().put("hash1","key2","value2");
    }
    //hash类型查询
    @Test
    public void hashQuery() {
   
        // 通过 h1 获取值
        System.err.println(redisTemplate.opsForHash().get("hash1","key1"));
        System.err.println(redisTemplate.opsForHash().entries("hash1"));
    }

求交集使用intersect( ) 方法,求差集使用difference( )方法,求并集使用union( )方法。某一音乐平台籍由这类方法来计算用户音乐偏好的重叠度,从而为推荐系统供予数据支撑 。

有序集合应用实践

有序集合借助redisTemplate.opsForZSet()来进行管理,其中每个元素都关联着一个用于排序的分数,这种结构极为契合排行榜类应用,像是游戏得分的排名,亦或是热点内容的排序,某个视频平台运用有序集合去维护视频热度榜,并且每五分钟实现一次更新。

package com.example.demo.controller;
import com.alibaba.fastjson.JSONObject;
import com.example.demo.DemoApplication;
import com.example.demo.bean.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.ArrayList;
import java.util.List;
@SpringBootTest(classes = DemoApplication.class)
@RunWith(SpringRunner.class)
public class RedisControllerTest {
   
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    //list类型添加
    @Test
    public void listAdd() {
   
        List list = new ArrayList<>();
        User user1 = new User("老赵", "123");
        User user2 = new User("老曹", "456");
        list.add(user1);
        list.add(user2);
        // 直接添加list
        redisTemplate.opsForList().leftPush("listKey",list);
        //循环添加元素
        redisTemplate.opsForList().leftPush("list1","v1");
        redisTemplate.opsForList().leftPush("list1","v2");
        redisTemplate.opsForList().leftPush("list1","v3");
    }
    //list类型查询
    @Test
    public void listQuery() {
   
        System.err.println(redisTemplate.opsForList().leftPop("listKey"));
        // 通过 list1 从队列左侧取出并删除数据
        System.err.println(redisTemplate.opsForList().leftPop("list1"));
        // 通过 list1 从队列右侧取出并删除数据
        System.err.println(redisTemplate.opsForList().rightPop("list1"));
    }

add()方法会去添加元素且添加分数,rangeByScore()依据分数范围来获取元素。于实际应用当中,这样的方法能够快速地去获取前N名数据,然而却不需要去处理全部一系列的数据集。

键值删除与管理

Redis模板提供了一整套的键值去除方案,涵盖单个去除以及批量去除功能。合理得体的键值管控对于系统性能来讲是相当关键的,有一个互联网公司的监测数据表明,适时地清理过期的缓存能够让内存使用降低到35% 。

除了采取直接删除这项措施之外,还能够进行过期时间的设置,进而使得缓存自行失效。这样一种机制,在验证码存储这类临时数据相关场景当中,是格外具备有用价值的,它有效地规避了手动清理所存在的复杂性情况。

package com.example.demo.controller;
import com.alibaba.fastjson.JSONObject;
import com.example.demo.DemoApplication;
import com.example.demo.bean.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.ArrayList;
import java.util.List;
@SpringBootTest(classes = DemoApplication.class)
@RunWith(SpringRunner.class)
public class RedisControllerTest {
   
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    //set(无序集合)类型添加
    @Test
    public void setAdd() {
   
        User user1 = new User("老赵", "123");
        User user2 = new User("老曹", "456");
        // 添加数据
        redisTemplate.opsForSet().add("set1","v1","v2","v3");
        redisTemplate.opsForSet().add("set2","v1");
        redisTemplate.opsForSet().add("set3",user1, user2);
    }
    //set(无序集合)类型查询
    @Test
    public void setQuery() {
   
        // 求交集
        System.err.println(redisTemplate.opsForSet().intersect("set1","set2"));
        // 求差集
        System.err.println(redisTemplate.opsForSet().difference("set1","set2"));
        // 求并集
        System.err.println(redisTemplate.opsForSet().union("set1","set2"));
        System.err.println(redisTemplate.opsForSet().members("set3"));
    }

在实际的相关开发情形当中,众人是更加偏向于去选取StringRedisTemplate还是RedisTemplate来针对不同的数据类型予以处理呢,欢迎于评论区段落分享你的项目经历经验,要是觉得这篇文章具备一定的帮助作用,请进行点赞给予支持并且分享给更多的从事开发方向的人员 。

责任编辑:CQITer新闻报料:400-888-8888   本站原创,未经授权不得转载
继续阅读
热新闻
推荐
关于我们联系我们免责声明隐私政策 友情链接