????????在平常的開發過程中,我們經常會用到緩存的技術。比如,驗證碼60秒后過期、計數器的實現、商品信息存儲在緩存中快速展示等。那么,項目中經常會使用到的便是 redis 緩存。redis 在內存中操作,讀寫快。Redis 常用的數據類型有五種,String、List、Hash、Set、Sorted Set。那么,今天我們總結下項目中引入 Redis 及常見數據類型操作。
? ? ?一:概述
????????Redis 基于內存的數據結構存儲系統,主要用于緩存、分布式鎖等場景。數據結構豐富:Redis 支持多種數據結構,常用的如字符串(String)、列表(List)、哈希(Hash)、集合(Set)、有序集合(Sorted Set)等。可以支持不同業務場景的使用。
????????Redis 將數據存儲在內存中,讀寫快。內存的高速訪問特性使得 Redis 可以在短時間內處理大量的請求,適用于對性能要求極高的場景,如實時數據處理、緩存等。Redis 也提供了持久化機制,如 RDB(Redis Database)快照和 AOF(Append Only File)日志,能夠將內存中的數據定期或實時地保存到磁盤上,以防止數據丟失。
????????Redis 的命令具有原子性,即一個命令要么完全執行,要么完全不執行,不會出現部分執行的情況。這保證了數據的一致性和完整性。
? ? ? 二:引入依賴
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId><version>2.1.5.RELEASE</version> <!-- 版本與 Spring Boot 保持一致 -->
</dependency>
? ? ? ? 注意:引入 Redis 的版本與 Springboot 版本保持一致。
? ? ?三:redis 連接信息配置
? ? ? ? 1:如果 Spring boot 2.x 版本,那么在 application.yml 中配置 redis 連接信息如下:
spring:redis:# 連接地址host: 127.0.0.1# 端口port: 6379# 數據庫database: 0# 用戶名# username: username# 密碼password: passrord# 連接超時# connect-timeout: 5s# 讀超時# timeout: 30
? ? ? ? 2:如果 Spring boot 3.x 版本,那么在 application.yml 中配置 redis 連接信息如下:
spring:data:redis:# 連接地址host: 127.0.0.1# 端口port: 6379# 數據庫database: 0# 用戶名# username: username# 密碼password: passrord# 連接超時# connect-timeout: 5s# 讀超時# timeout: 30
????????注意:Spring Boot 3.x 對配置屬性進行了更嚴格的規范化,將數據相關的配置統一到 spring.data 命名空間下,提高一致性和可維護性。
? ? ?四:五種常用數據類型
? ? ?1:字符串 String
? ? ? ? 應用場景:驗證碼、計數器、分布式鎖,最大可存儲 512 m。
? ? ? ? 代碼示例:
// 操作字符串
// 不設置過期時間
stringRedisTemplate.opsForValue().set("11", "蜜薯");
// 設置過期時間為 10 秒鐘
stringRedisTemplate.opsForValue().set("12", "馬鈴薯", Duration.ofSeconds(10));
// 設置過期時間為 10 秒鐘
stringRedisTemplate.opsForValue().set("13", "紅薯", 10, TimeUnit.SECONDS);
// 獲取值
String value11 = stringRedisTemplate.opsForValue().get("11");
log.info("value11={}", JSONUtil.toJsonStr(value11));
??????2:列表 List
????????應用場景:有序元素集合 用戶搜索近十條歷史記錄、最新消息展示
????????代碼示例:
// 有序元素集合 用戶搜索近十條歷史記錄、最新消息展示
// 操作 list
List<SysDictData> dictDataList = new ArrayList<>();
for (int i = 0; i < 10; i++) {SysDictData dictData = new SysDictData();dictData.setDictCode(Long.valueOf(i));dictData.setDictLabel("字典" + i);dictDataList.add(dictData);
}
// 將 list 對象轉為 String
// 不設置過期時間
stringRedisTemplate.opsForValue().set("dictListString", JSONUtil.toJsonStr(dictDataList));
// 設置過期時間
stringRedisTemplate.opsForValue().set("dictListString", JSONUtil.toJsonStr(dictDataList), 10, TimeUnit.MINUTES);
String dictListString = stringRedisTemplate.opsForValue().get("dictListString");
List<SysDictData> dictDataListRedis = JSONUtil.toList(dictListString, SysDictData.class);
log.info("dictDataListRedis={}", JSONUtil.toJsonStr(dictDataListRedis));stringRedisTemplate.opsForList().leftPush("dictList", "字典1");
stringRedisTemplate.opsForList().leftPush("dictList", "字典2");
stringRedisTemplate.opsForList().leftPush("dictList", "字典3");
stringRedisTemplate.opsForList().leftPush("dictList", "字典4");stringRedisTemplate.opsForList().rightPush("dictList", "字典5");
// 取出 list 中所有的值
List<String> dictListValueAll = stringRedisTemplate.opsForList().range("dictList", 0, -1);
log.info("dictListValueAll={}", JSONUtil.toJsonStr(dictListValueAll));
// 取出 list 中前三條數據
List<String> dictListValueThree = stringRedisTemplate.opsForList().range("dictList", 0, 2);
log.info("dictListValueThree={}", JSONUtil.toJsonStr(dictListValueThree));
? ? ? 3:哈希 Hash
? ? ? ? 應用場景:field-value 映射表,適合存儲對象,用戶屬性信息、商品信息
? ? ? ? 代碼示例:
// 添加 111 用戶
stringRedisTemplate.opsForHash().put("111", "name", "張三");
stringRedisTemplate.opsForHash().put("111", "age", "98");
stringRedisTemplate.opsForHash().put("111", "phone", "123456789");
stringRedisTemplate.opsForHash().put("111", "address", "西安");
// 添加 222 用戶
stringRedisTemplate.opsForHash().put("222", "name", "李四");
stringRedisTemplate.opsForHash().put("222", "age", "88");
stringRedisTemplate.opsForHash().put("222", "phone", "123456789");
stringRedisTemplate.opsForHash().put("222", "address", "寶雞");
// 獲取全部元素
Map<Object, Object> scoresMap = stringRedisTemplate.opsForHash().entries("scores");
log.info("scoresMap={}", JSONUtil.toJsonStr(scoresMap));
// 獲取某個 key 的值
Object scoresSingleMap = stringRedisTemplate.opsForHash().get("scores", "112");
log.info("scoresSingleMap={}", JSONUtil.toJsonStr(scoresSingleMap));
? ? ? 4:集合 Set
? ? ? ? 應用場景:無序、元素不可重復 抽獎系統、計數器
? ? ? ? 代碼示例:
stringRedisTemplate.opsForSet().add("cities", "11", "12", "13", "14", "15", "16");
// 獲取到所有值 適合數據量小
Set<String> setCitiesAll = stringRedisTemplate.opsForSet().members("cities");
log.info("setCitiesAll={}", JSONUtil.toJsonStr(setCitiesAll));
? ? ? 5:有序集合 Sorted Set
? ? ? ? 應用場景:帶分數的 set,分數可以重復,元素唯一 ? 排行榜、范圍查詢
? ? ? ? 代碼示例:
stringRedisTemplate.opsForZSet().add("studentIds", "111", 1);
stringRedisTemplate.opsForZSet().add("studentIds", "112", 2);
stringRedisTemplate.opsForZSet().add("studentIds", "113", 3);
stringRedisTemplate.opsForZSet().add("studentIds", "114", 4);
stringRedisTemplate.opsForZSet().add("studentIds", "115", 5);
stringRedisTemplate.opsForZSet().add("studentIds", "116", 6);
// 數據量小,全部獲取
Set set = stringRedisTemplate.opsForZSet().range("studentIds", 0, -1);
log.info("studentIds set={}", JSONUtil.toJsonStr(set));
? ? ? ? 如果數據量大,則分頁獲取:
// 獲取數據總條數
Long totalSize = stringRedisTemplate.opsForZSet().size("studentIds");
// 分頁獲取key中的數據
Set<String> studentIdsSet = new HashSet<>();
// 每頁獲取的記錄數
int pageSize = 2;
// 計算總頁數
int totalPages = (int) Math.ceil(totalSize / (double) pageSize);
for (int page = 0; page < totalPages; page++) {// 每次獲取數據開始的位置long start = (long) page * pageSize;// 每次獲取數據結束的位置long end = start + pageSize - 1;// 獲取數據Set<ZSetOperations.TypedTuple<String>> setData = stringRedisTemplate.opsForZSet().rangeWithScores("studentIds", start, end);if (CollUtil.isNotEmpty(setData)) {// 將數據進行轉換Set<String> cacheData = setData.stream().map(item -> {String value = JSONObject.parseObject(item.getValue(), String.class);return value;}).filter(Objects::nonNull).collect(Collectors.toSet());studentIdsSet.addAll(cacheData);}
}
? ? ?五:總結
? ? ? ?以上為項目中引入 Redis 的基本步驟,以及常見五種數據類型的應用場景及操作方法。
???????Redis 廣泛應用于緩存、消息隊列、實時分析、分布式鎖等場景。它支持多種數據結構(如 String、List、Hash、Set、Sorted Set等),并提供了持久化、高可用、集群、事務、Lua 腳本、發布/訂閱等。
???????Redis 數據存儲在內存中,讀寫速度快,適用于高并發低延遲場景。同時,它支持 RDB(快照)和 AOF(日志追加)持久化,確保數據安全。