Redis的五種基本數(shù)據(jù)類型解讀(String、List、Hash、Set、ZSet)
1.概述
Redis共有五種基本數(shù)據(jù)類型:String(字符串)、List(列表)、Hash(散列)、Set(集合)、ZSet(有序集合)。
這些基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)支持豐富的原子操作,底層通過內(nèi)存壓縮算法(如ziplist、intset)實現(xiàn)空間與速度的平衡。本文將詳細(xì)介紹五種基礎(chǔ)數(shù)據(jù)結(jié)構(gòu),幫助大家更好地理解Redis基礎(chǔ)數(shù)據(jù)的使用及原理。
2.基本數(shù)據(jù)類型詳解
2.1 String
String類型是Redis中使用最多的類型,key是唯一標(biāo)識,value代表對應(yīng)key存儲的值,value可以是字符串、數(shù)字(整型或浮點數(shù)),value最多可以容納的數(shù)據(jù)長度是512M。
2.1.1 String類型常用指令
| 命令 | 說明 |
|---|---|
| SET key value | 設(shè)置指定 key 的值 |
| GET key | 獲取指定 key 的值 |
| MSET key1 value1 key2 value2 …… | 批量設(shè)置key、value |
| MGET key1 key2 … | 獲取一個或多個指定 key 的值 |
| STRLEN key | 返回key所存儲的字符串長度 |
| SETNX key value | key 不存在時設(shè)置 key 的值 |
| SETEX key seconds value | 設(shè)置key、value和過期時間 |
| INCR key | 將 key 中儲存的數(shù)字值增一 |
| DECR key | 將 key 中儲存的數(shù)字值減一 |
| APPEND key value | 向當(dāng)前key的字符串后面追加字符串,key不存在相當(dāng)于set key value |
| GETRANGE key start end | 截取key以start為起點,end為終點的字符串 |
| KEYS * | 獲取當(dāng)前數(shù)據(jù)庫所有的key(通用指令) |
| EXISTS key | 判斷指定 key 是否存在(通用指令) |
| DEL key | 刪除key(通用指令) |
| GETSET key value | 先get后set |
2.1.2 指令實測
> set books java OK > get books java > MSET name zhangsan age 18 OK > mget name age zhangsan 18 > STRLEN name 8 > SETNX name zhangsan 0 > SETEX address 30 beijing OK > TTL address 18 > INCR age 19 > INCR age 20 > GET age 20 > DECR age 19 > APPEND name ',hello world' 20 > GET name zhangsan,hello world > GETRANGE name 0 4 zhang > GETRANGE name 0 3 zhan > keys * name key1 count books key2 age > EXISTS count 1 > del count 1 > GETSET db redis null > GET db redis
2.1.3 應(yīng)用場景
1.計數(shù)器
- 例如,可以用來記錄網(wǎng)站的訪問次數(shù)、用戶登錄次數(shù)等。
- 使用場景:使用 INCR 和 DECR 指令對計數(shù)器進(jìn)行遞增或遞減操作,實現(xiàn)記錄網(wǎng)站的訪問次數(shù)、用戶登錄次數(shù)等。
2.緩存功能
- 例如,存儲用戶信息、配置信息等。
- 使用場景:使用 SET 和 GET 指令實現(xiàn)簡單的鍵值對緩存。
3.分布式鎖
- 例如:在分布式系統(tǒng)中確保某個操作在同一時間內(nèi)只能由一個實例執(zhí)行。
- 使用場景:使用 SET 指令的 NX(僅當(dāng)鍵不存在時設(shè)置)和 EX(設(shè)置過期時間)選項實現(xiàn)分布式鎖。
2.2 List
2.2.1 List類型常用指令
| 命令 | 說明 |
|---|---|
| LPUSH key value1 value2 … | 在指定列表的頭部(左邊)添加一個或多個元素 |
| RPUSH key value1 value2 … | 在指定列表的頭部(右邊)添加一個或多個元素 |
| LSET key index value | 將指定列表索引 index 位置的值設(shè)置為 value |
| LPOP key | 移除并獲取指定列表的第一個元素(最左邊) |
| RPOP key | 移除并獲取指定列表的最后一個元素(最右邊) |
| LLEN key | 獲取列表元素數(shù)量 |
| LRANGE key start end | 獲取列表 start 和 end 之間 的元素 |
2.2.2 List指令實測
> LPUSH books java python go 3 > LLEN books 3 > LRANGE books 0 -1 go python java > LPUSH books javascript 4 > LRANGE books 0 -1 javascript go python java > RPUSH books c 5 > LRANGE books 0 -1 javascript go python java c > RPOP books c > LRANGE books 0 -1 javascript go python java > LPOP books javascript > LRANGE books 0 -1 go python java > LINDEX books 0 go > LINDEX books 2 java > LSET books 2 javascript OK > LRANGE books 0 -1 go python javascript
2.2.3 使用場景
1.簡單消息隊列
- 例如,通過訂閱同一個list的key實現(xiàn)消息隊列等。
- 使用場景:通過LPUSH/RPOP或者RPUSH/LPOP可以實現(xiàn)簡易消息隊列,實現(xiàn)數(shù)據(jù)先進(jìn)先出。
2.模擬棧實現(xiàn)
- 例如,通過模擬棧先進(jìn)后出。
- 使用場景:通過LPUSH/LPOP或者RPUSH/RPOP可以實現(xiàn)棧,實現(xiàn)數(shù)據(jù)后進(jìn)先出,實現(xiàn)特點場景下的規(guī)則解析。
2.3 Hash
2.3.1 Hash類型常用指令
| 命令 | 說明 |
|---|---|
| HSET key field value | 設(shè)置指定哈希表中指定字段的值 |
| HGET key field | 獲取指定哈希表中指定字段的值 |
| HMSET key field1 value1 field2 value2 … | 同時設(shè)置一個或多個 field-value 到指定哈希表中 |
| HMGET key field1 field2 … | 獲取指定哈希表中一個或者多個指定字段的值 |
| HGETALL key | 獲取指定哈希表中所有的鍵值對 |
| HEXISTS key field | 查看指定哈希表中指定的字段是否存在 |
| HDEL key field1 field2 … | 刪除一個或多個哈希表字段 |
| HLEN key | 獲取指定哈希表中字段的數(shù)量 |
| HSETNX key field value | 當(dāng)指定哈希表中的字段不存在時,才添加值 |
| HINCRBY key field increment | 對指定哈希中的指定字段做運(yùn)算操作(正數(shù)為加,負(fù)數(shù)為減) |
2.3.2 Hash指令實測
> HSET userInfo-1 name zhangsan 1 > HSET userInfo-1 age 18 1 > HSET userInfo-1 sex male 1 > HGET userInfo-1 name zhangsan > HMSET userInfo-2 name lisi age 20 sex female OK > HMGET userInfo-1 name age sex zhangsan 18 male > HGETALL userInfo-1 name zhangsan age 18 sex male > HEXISTS userInfo-1 name 1 > HDEL userInfo-1 sex 1 > HGETALL userInfo-1 name zhangsan age 18 > HLEN userInfo-1 2 > HSETNX userInfo-1 name zhangsan 0 > HINCRBY userInfo-1 age 5 23 > HGETALL userInfo-1 name zhangsan age 23
2.3.2 Hash使用場景
1.對象信息存儲
- 例如,存儲用戶信息等。
- 使用場景:以信息標(biāo)簽+用戶唯一id作為key,屬性分別是作為field,這樣相對于String存儲的優(yōu)勢是提升了效率(string類型需要進(jìn)行數(shù)據(jù)轉(zhuǎn)換后才能獲取到值)。
2.購物車功能
- 例如,實現(xiàn)購物車功能
- 使用場景:將用戶id作為key,商品id作為field,field的值為商品數(shù)量。
2.4 Set
2.4.1 Set類型常用指令
| 命令 | 說明 |
|---|---|
| SADD key member1 member2 … | 向指定集合添加一個或多個元素 |
| SMEMBERS key | 獲取指定集合中的所有元素 |
| SCARD key | 獲取指定集合的元素數(shù)量 |
| SREM key memeber | 移除集合中的指定元素 |
| SISMEMBER key member | 判斷指定元素是否在指定集合中 |
| SINTER key1 key2 … | 獲取給定所有集合的交集 |
| SINTERSTORE destination key1 key2 … | 將給定所有集合的交集存儲在 destination 中 |
| SUNION key1 key2 … | 獲取給定所有集合的并集 |
| SUNIONSTORE destination key1 key2 … | 將給定所有集合的并集存儲在 destination 中 |
| SDIFF key1 key2 … | 獲取給定所有集合的差集 |
| SDIFFSTORE destination key1 key2 … | 將給定所有集合的差集存儲在 destination 中 |
| SPOP key count | 隨機(jī)移除并獲取指定集合中一個或多個元素 |
| SRANDMEMBER key count | 隨機(jī)獲取指定集合中指定數(shù)量的元素 |
2.4.2 Set指令實測
> sadd db oracle mysql sqlite 3 > SADD db mysql 0 > SMEMBERS db oracle mysql sqlite > SCARD db 3 > SISMEMBER db oracle 1 > SREM db mysql 1 > SMEMBERS db oracle sqlite > SADD db1 mysql oracle hbase 3 > SINTERSTORE db2 db db1 1 > SMEMBERS db2 oracle > SUNION db db1 oracle sqlite mysql hbase > SDIFF db db1 sqlite > SRANDMEMBER db1 2 oracle hbase > SPOP db1 2 oracle hbase > SMEMBERS db1 mysql
2.4.3 Set使用場景
1.共同關(guān)注好友
- 例如,微博、B站等共同關(guān)注博主等。
- 使用場景:可以將A用戶的關(guān)注博主、B用戶的關(guān)注博主分別做一個Set集合,通過取并集獲取共同關(guān)注對象。
2.獲取隨機(jī)值
- 例如,實現(xiàn)某些具體場景隨機(jī)值獲取
- 使用場景:將用戶id作為一個Set集合,通過SPOP指令隨機(jī)獲取用戶id,實現(xiàn)抽獎等場景功能。
3.快速去重
- 在某些應(yīng)用中,可以使用有序集合來管理定時任務(wù),其中任務(wù)的執(zhí)行時間作為分?jǐn)?shù)存儲。
- 使用場景:獲取網(wǎng)站UV數(shù)據(jù),將網(wǎng)站域名作為key,用戶唯一標(biāo)識作為集合值,實現(xiàn)快速去重,獲取當(dāng)日、周該網(wǎng)站UV數(shù)據(jù)。
2.5 ZSet
2.5.1 ZSet類型常用指令
有序集合相對于Set增加了一個權(quán)重參數(shù)score,集合中的元素能夠按照score進(jìn)行有序排列,也可以按照score的范圍來獲取集合中的元素。
| 命令 | 說明 |
|---|---|
| ZADD key score1 member1 score2 member2 … | 向指定有序集合中添加一個或多個元素 |
| ZSCORE key member | 獲取有序集合中指定元素的score值 |
| ZCARD KEY | 獲取指定有序集合的元素數(shù)量 |
| ZRANGEBYSCORE key min max [WITHSCORES] | 根據(jù)分?jǐn)?shù)獲取有序集合中元素 |
| ZREVRANK key member | 返回有序集中成員的排名,排名以0為底,分?jǐn)?shù)值最大的成員排名為0 |
| ZLEXCOUNT key min max | 對于一個所有成員的分值都相同的有序集合鍵 key 來說, 這個命令會返回該集合中, 成員介于 min 和 max 范圍內(nèi)的元素數(shù)量。 |
| ZINTERSTORE destination numkeys key1 key2 … | 將給定所有有序集合的交集存儲在destination中,對相同元素對應(yīng)的score值進(jìn)行sum聚合操作,numkeys 為集合數(shù)量 |
| ZUNIONSTORE destination numkeys key1 key2 … | 求并集,其中給定 key 的數(shù)量必須以 numkeys 參數(shù)指定,并將該并集(結(jié)果集)儲存到 destination |
| ZDIFFSTORE destination numkeys key1 key2 … | 求差集,其中給定 key 的數(shù)量必須以 numkeys 參數(shù)指定,并將該并集(結(jié)果集)儲存到 destination |
| ZRANGE key start end | 獲取指定有序集合 start 和 end 之間的元素,score由低到高排序 |
| ZREVRANGE key start end | 獲取指定有序集合 start 和 end 之間的元素,score由低到高排序 |
| ZREM key member | 移除有序集合中指定元素 |
2.5.3 ZSet指令實測
> zadd salary 3000 zhangsan 4000 lisi 8000 wangwu 3 > ZSCORE salary zhangsan 3000 > ZADD salary 12000 zhaoliu 1 > ZCARD salary 4 > ZRANGEBYSCORE salary 3000 5000 zhangsan lisi > ZRANGEBYSCORE salary 3000 5000 WITHSCORES zhangsan 3000 lisi 4000 > ZREVRANK salary zhaoliu 0 > ZREVRANK salary wangwu 1 > ZINTERSTORE salary2 2 salary salary1 1 > ZRANGE salary 0 -1 withscores zhangsan 3000 lisi 4000 wangwu 8000 > ZRANGE salary2 0 -1 withscores zhangsan 6000 > ZUNIONSTORE salary3 2 salary salary1 5 > ZRANGE salary3 0 -1 withscores lisi 4000 tony 5000 tom 6000 zhangsan 6000 wangwu 8000 > ZDIFFSTORE salary4 2 salary salary1 2 > ZRANGE salary4 0 -1 withscores lisi 4000 wangwu 8000 > ZREVRANGE salary 0 -1 wangwu lisi zhangsan > ZREM salary zhangsan 1
2.5.3 ZSet使用場景
1.排行榜系統(tǒng)
- 例如,游戲中的玩家分?jǐn)?shù)排行榜、視頻網(wǎng)站上的視頻點贊數(shù)排行榜等。
- 使用場景:可以實時更新分?jǐn)?shù),并利用 ZADD 命令添加或更新元素及其分?jǐn)?shù),使用 ZREVRANGE 或 ZREVRANGEBYSCORE 命令獲取排名靠前的元素。
2.延遲消息隊列
- 使用有序集合存儲消息及其延遲時間(以時間戳或相對延遲時間表示),然后通過 ZRANGEBYSCORE 命令獲取當(dāng)前時間之前的所有消息進(jìn)行處理。
- 使用場景:可以確保消息按照預(yù)定的延遲時間被處理,非常適合需要延遲處理的場景。
3.定時任務(wù)調(diào)度
- 在某些應(yīng)用中,可以使用有序集合來管理定時任務(wù),其中任務(wù)的執(zhí)行時間作為分?jǐn)?shù)存儲。
- 使用場景:通過定期查詢當(dāng)前時間之前的任務(wù)并執(zhí)行它們,可以實現(xiàn)一個簡單的任務(wù)調(diào)度器。
3.代碼實現(xiàn)
3.1 pom文件引入
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
3.2 RedisUtil工具類實現(xiàn)
import com.alibaba.fastjson.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.data.redis.core.types.RedisClientInfo;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
@Component
public class RedisUtil {
private static final Logger LOG = LoggerFactory.getLogger(RedisUtil.class);
/**
* 默認(rèn)過期時間,單位:秒,即,24個小時 后 過期
*/
public static final long DEFAULT_EXPIRE = 60 * 60 * 24;
@Resource
private RedisTemplate<String, Object> redisTemplate;
@Resource(name = "strRedisTemplate")
private RedisTemplate<String, String> stringRedisTemplate;
/**
* set 方法
*
* @param key key
* @param value value
*/
public void set(String key, Object value) {
set(key, value, null);
}
public void setWithDefaultExpire(String key, Object value) {
set(key, value, DEFAULT_EXPIRE);
}
/**
* @param key redis key
* @param value redis值
* @param expire 過期時間,秒
*/
public void set(String key, Object value, Long expire) {
if (expire != null && expire.longValue() != 0L) {
redisTemplate.boundValueOps(key).set(value, expire, TimeUnit.SECONDS);
} else {
redisTemplate.boundValueOps(key).set(value);
}
}
/**
* @param key redis key
* @param value redis值
* @param expire 過期時間,秒
*/
public void setString(String key, String value, Long expire) {
if (expire != null && expire.longValue() != 0L) {
stringRedisTemplate.boundValueOps(key).set(value, expire, TimeUnit.SECONDS);
} else {
stringRedisTemplate.boundValueOps(key).set(value);
}
}
public Double increment(String key, double score) {
return redisTemplate.opsForValue().increment(key, score);
}
/**
* 獲取redis value
*
* @param key
* @return Object 對象
*/
public Object get(String key) {
return redisTemplate.opsForValue().get(key);
}
/**
* 判斷key是否存在
*
* @param key
* @return Set 集合
*/
public Set<String> keys(String key) {
return redisTemplate.keys(key);
}
public void deleteKeys(Set<String> keys) {
redisTemplate.delete(keys);
}
public String getString(String key) {
return stringRedisTemplate.opsForValue().get(key);
}
public void delete(String key) {
redisTemplate.delete(key);
}
public void expire(String key, Long expire) {
redisTemplate.expire(key, expire, TimeUnit.SECONDS);
}
public Boolean hsetAbsent(String key, String hkey, Object value) {
return redisTemplate.opsForHash().putIfAbsent(key, hkey, value);
}
public void hset(String key, String hkey, Object value) {
redisTemplate.opsForHash().put(key, hkey, value);
}
public void hmset(String key, Map<?, ?> hashMap) {
redisTemplate.opsForHash().putAll(key, hashMap);
}
public Long lpushString(String key, String val) {
return stringRedisTemplate.boundListOps(key).leftPush(val);
}
public String rpopString(String key) {
return stringRedisTemplate.boundListOps(key).rightPop();
}
public Long llen(String key) {
return stringRedisTemplate.boundListOps(key).size();
}
public Properties info() {
RedisConnection connection = null;
Properties p = null;
try {
connection = redisTemplate.getConnectionFactory().getConnection();
p = connection.info("memory");
} catch (Exception e) {
LOG.error("redis獲取連接失敗", e);
} finally {
if (connection != null) {
connection.close();
}
}
return p;
}
public String clients() {
List<RedisClientInfo> clientList = redisTemplate.getClientList();
return JSON.toJSONString(clientList);
}
/**
* 左邊入隊
*/
public Long lpush(String key, Object val) {
return redisTemplate.boundListOps(key).leftPush(val);
}
/**
* 右邊出隊
*/
public Object rpop(String key) {
return redisTemplate.boundListOps(key).rightPop();
}
/**
* 右邊出隊
*/
public String rpop(String key, Integer timeout) {
return stringRedisTemplate.opsForList().rightPop(key, timeout, TimeUnit.SECONDS);
}
public Object hget(String key, String hkey) {
return redisTemplate.opsForHash().get(key, hkey);
}
public String hgetStr(String key, String hkey) {
return (String) stringRedisTemplate.opsForHash().get(key, hkey);
}
public Long hdel(String key, String hkey) {
return redisTemplate.opsForHash().delete(key, hkey);
}
public void hincrement(String key, String hkey) {
redisTemplate.opsForHash().increment(key, hkey, 1);
}
public boolean hasKey(String key) {
return redisTemplate.hasKey(key);
}
public Double zscore(String key, Object val) {
return stringRedisTemplate.opsForZSet().score(key, val);
}
public boolean zadd(String key, String value, double score) {
return stringRedisTemplate.opsForZSet().add(key, value, score);
}
public Long zadd(String key, Set<ZSetOperations.TypedTuple<String>> tuples) {
return stringRedisTemplate.opsForZSet().add(key, tuples);
}
public void zaddObj(String key, Object value, double score) {
redisTemplate.opsForZSet().add(key, value, score);
}
public Long removeRangeByScoreObj(String key, double minScore, double maxScore) {
return redisTemplate.opsForZSet().removeRangeByScore(key, minScore, maxScore);
}
public Long removeRangeByObj(String key, Object value) {
return redisTemplate.opsForZSet().remove(key, value);
}
public Long removeRangeByScoreStr(String key, double minScore, double maxScore) {
return stringRedisTemplate.opsForZSet().removeRangeByScore(key, minScore, maxScore);
}
public Double zStringScore(String key, Object value) {
return stringRedisTemplate.opsForZSet().score(key, value);
}
public Set<String> zrangeByScore(String key, double minScore, double maxScore) {
return stringRedisTemplate.opsForZSet().rangeByScore(key, minScore, maxScore);
}
public Set<String> zreverseRangeByScore(String key, double minScore, double maxScore) {
return stringRedisTemplate.opsForZSet().reverseRangeByScore(key, minScore, maxScore);
}
public Set<String> zrangeByScore(String key, double minScore, double maxScore, long offset, long count) {
return stringRedisTemplate.opsForZSet().rangeByScore(key, minScore, maxScore, offset, count);
}
public Set<String> zreverseRangeByScore(String key, double minScore, double maxScore, long offset, long count) {
return stringRedisTemplate.opsForZSet().reverseRangeByScore(key, minScore, maxScore, offset, count);
}
public Set zrangeByScoreObj(String key, double minScore, double maxScore) {
return redisTemplate.opsForZSet().rangeByScore(key, minScore, maxScore);
}
public Long zrank(String key, String value) {
return stringRedisTemplate.opsForZSet().rank(key, value);
}
public void zremObj(String key, String member) {
redisTemplate.opsForZSet().remove(key, member);
}
public Long zremStr(String key, String member) {
return stringRedisTemplate.opsForZSet().remove(key, member);
}
public Map<Object, Object> hGetAll(String key) {
return redisTemplate.opsForHash().entries(key);
}
public Set<Object> hkeys(String key){
return redisTemplate.opsForHash().keys(key);
}
public List<Object> hValues(String key) {
return redisTemplate.opsForHash().values(key);
}
public Map<String, String> hGetAllConvertString(String key) {
Map<Object, Object> tmp = redisTemplate.opsForHash().entries(key);
return tmp != null ? convertToString(tmp) : null;
}
public Set<ZSetOperations.TypedTuple<Object>> rangeByScoreWithScores(String name, double min, double max, long offset, long count) {
return redisTemplate.opsForZSet().rangeByScoreWithScores(name, min, max, offset, count);
}
public Set<ZSetOperations.TypedTuple<String>> strRangeByScoreWithScores(String name, double min, double max, long offset, long count) {
return stringRedisTemplate.opsForZSet().rangeByScoreWithScores(name, min, max, offset, count);
}
public Set<String> strZRange(String key, int start, int end) {
return stringRedisTemplate.opsForZSet().range(key, start, end);
}
public Set<ZSetOperations.TypedTuple<String>> strZRangeWithScores(String key, int start, int end) {
return stringRedisTemplate.opsForZSet().rangeWithScores(key, start, end);
}
public Double strIncrementScore(String key, String value, double delta) {
return stringRedisTemplate.opsForZSet().incrementScore(key, value, delta);
}
public Double incrementScore(String key, String value, double score) {
return redisTemplate.opsForZSet().incrementScore(key, value, score);
}
public Set<String> members(String key) {
return stringRedisTemplate.opsForSet().members(key);
}
public boolean isMembers(String key, String value) {
return stringRedisTemplate.opsForSet().isMember(key, value);
}
public Set<String> sMembersStr(String key) {
return stringRedisTemplate.opsForSet().members(key);
}
public void sAddStr(String key, String value) {
stringRedisTemplate.opsForSet().add(key, value);
}
public void sAdd(String key, Object val) {
redisTemplate.opsForSet().add(key, val);
}
public String sPop(String key) {
return stringRedisTemplate.opsForSet().pop(key);
}
public void leftPush(String key, String value) {
stringRedisTemplate.boundListOps(key).leftPush(value);
}
public void sRemoveStr(String key, String value) {
stringRedisTemplate.opsForSet().remove(key, value);
}
public void publish(String channel, String value) {
stringRedisTemplate.convertAndSend(channel, value);
}
public static Map<String, String> convertToString(Map<Object, Object> map) {
Objects.requireNonNull(map);
Map<String, String> result = new ConcurrentHashMap<>(map.size());
map.forEach((key, value) -> result.put(key.toString(), value.toString()));
return result;
}
}
4.總結(jié)
1.本文主要講解redis的基礎(chǔ)數(shù)據(jù)類型和使用方式,同時實操指令,說明其使用場景;
2.本文利用JAVA語言實現(xiàn)了個Redis工具類,對RedisTemplate做了二次封裝,供大家參考;
3.關(guān)于Redis的底層數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)存儲原理,本文沒有詳細(xì)敘述,可參考文獻(xiàn)部分,寫的都十分詳細(xì)。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
- redis string實現(xiàn)共享會話和手機(jī)驗證碼應(yīng)用場景
- redis數(shù)據(jù)結(jié)構(gòu)之String詳解
- Redis字符串String操作詳解從基礎(chǔ)到高級應(yīng)用小結(jié)
- SpringBoot3.4.0無法找到StringRedisTemplate?bean的問題Consider?defining?a?bean?of?type?‘org.springframework
- Redis序列化反序列化不一致導(dǎo)致String類型值多了雙引號問題
- Springboot中RedisTemplate設(shè)置String、Hash、List過期時間
- Java中Redis存儲String類型會有亂碼的問題及解決方案
相關(guān)文章
關(guān)于Redis最常見的十道面試題總結(jié)大全
Redis作為一個高性能的內(nèi)存數(shù)據(jù)存儲系統(tǒng),具有快速讀寫、持久性、數(shù)據(jù)結(jié)構(gòu)多樣性等特點,廣泛應(yīng)用于各種應(yīng)用場景,這篇文章主要給大家介紹了關(guān)于Redis最常見的十道面試題總結(jié)的相關(guān)資料,需要的朋友可以參考下2024-07-07
異步redis隊列實現(xiàn) 數(shù)據(jù)入庫的方法
今天小編就為大家分享一篇異步redis隊列實現(xiàn) 數(shù)據(jù)入庫的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-10-10
redis連接報錯error:NOAUTH Authentication required
本文主要介紹了redis連接報錯error:NOAUTH Authentication required,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-05-05

