SpringBoot中的Redis?緩存問題及操作方法
1、五大基本數(shù)據(jù)類型和操作
1.1 字符串-string
命令 | 說明 |
---|---|
set key value | 如果key還沒有,那就可以添加,如果key已經(jīng)存在了,那會覆蓋原有key的值 |
get key | 如果key還沒有,獲取為(nil),代表key沒有被使用,如果key存在,可以獲取對應key的值 |
exists key | 判斷某個key是否存在,返回Integer值1 代表存在,如果 exists car2 則返回0,不存在 |
move key db | 將當前數(shù)據(jù)庫存在的鍵值移動到其它數(shù)據(jù)庫,其中db是數(shù)據(jù)庫的序號 |
expire key 秒鐘 | 為已經(jīng)存在的key設置過期時間,注意過期之后,從內(nèi)存中去掉了,是get不到的 |
ttl key | 查看還有多少秒過期,-1表示永不過期,-2表示已過期 |
type key | 命令用于返回 key 所儲存的值的類型 |
del key | 根據(jù)key值刪除 |
append key value | 根據(jù)key將其值進行字符串拼接 |
strlen key | 根據(jù)key獲取其值的字符串長度,字節(jié)數(shù) |
incr key | 對key對應數(shù)值進行加一操作,對應的字符串值必須是數(shù)值 |
decr key | 對key對應數(shù)值進行減一操作 |
incrby key 數(shù)值 | 對key對應數(shù)值按照指定的值進行遞增 |
decrby key 數(shù)值 | 對key對應數(shù)值按照指定的值進行遞減 |
getrange key 起始位置 結(jié)束位置 | 獲取指定區(qū)間內(nèi)的值,類似between。。。and的關系,起始位置為0,結(jié)束位置為-1 就是返回所有 |
setrange key 起始位置 具體值 | 設置指定區(qū)間內(nèi)的值,具體值會從起始位置開始覆蓋 |
setex key 過期秒值 真實值 | 設置帶過期時間的key,動態(tài)設置。 |
setnx key value | 只有在 key 不存在時,才會設置 key 的值,如果已經(jīng)存在了,不覆蓋,設置不了; |
setnx key value | 如果返回0 代表沒有設置成功,key對應值已經(jīng)存在,如果返回1代表設置成功;這個就是redis的分布式鎖命令,很重要; |
mset key1 val1 key2 val2 .... | 同時設置一個或多個 key-value 對 |
mget key1 key2 key3 .... | 獲取所有(一個或多個)給定 key 的值。 |
msetnx key1 val1 key2 val2 ..... | 同時設置一個或多個 key-value 對,當且僅當所有給定 key 都不存在 |
1.2 列表-list
list操作起來類似于棧;
命令 | 說明 |
---|---|
lpush key val1 val2 val3 .... | 從左側(cè)開始存放元素,先進后出 |
lrange key 起始位置 結(jié)束位置 | 從左側(cè)開始,指定范圍獲取元素,-1代表所有 |
rpush key val1 val2 val3 .... | 從右側(cè)開始存放元素,先進先出 |
lpop key | 從左側(cè)一次取出一個元素 |
rpop key | 從右側(cè)一次取出一個元素 |
lindex key index | 按照索引下標獲得元素(從左到右,左下標從0開始,如果是-1代表最后一個,-2代表倒數(shù)第二個) |
llen key | 獲取集合元素個數(shù) |
lrem key 個數(shù) 具體的值 | 從左往右刪除指定個數(shù)等于具體值的元素,返回的值為實際刪除的數(shù)量,個數(shù)0,表示刪除全部給定的值 |
ltrim key 開始index 結(jié)束index | 截取指定范圍的值后再賦值給key |
rpoplpush 源列表 目的列表 | 移除列表的最后一個元素,并將該元素添加到另一個列表并返回 |
lset key index value | 將key集合中的指定下標位置值改為value |
linsert key before/after 值1 值2 | 在list某個已有 值1 的前后再添加具體 值2 |
小結(jié):
- 它是一個字符串鏈表,left、right都可以插入添加;
- 如果鍵不存在,創(chuàng)建新的鏈表;
- 如果鍵已存在,新增內(nèi)容;
- 如果值全移除,對應的鍵也就消失了;
- 鏈表的操作無論是頭和尾效率都極高,但假如是對中間元素進行操作,效率就很慘淡了;
1.3 集合-set
命令 | 說明 |
---|---|
sadd key val1 val2 ... | 集合set中添加元素,如果有重復元素會自動去除 |
smembers key | 查看集合中的元素 |
sismember key val | 判斷val是否在set集合中,如果在返回1 ,不在返回0 |
scard key | 獲取集合里面的元素個數(shù) |
srem key value | 刪除集合中元素 |
srandmember key 某個整數(shù) | 隨機出幾個數(shù),如果超過最大數(shù)量就全部取出 |
srandmember key 某個整數(shù) | 如果寫的值是負數(shù),比如-3 ,表示需要取出3個,但是可能會有重復值。 |
spop key | 隨機出棧 |
smove key1 key2 | 將key1里的某個值賦給key2 |
sdiff key1 key2 | 在第一個set里面而不在后面任何一個set里面的項 |
sinter key1 key2 | 在兩個set中都有的值的交集返回 |
sunion key1 key2 | 在兩個set中所有的值的集合返回,會自動排除重復 |
1.4 鍵值對-hash
K V模式不變,但V是一個鍵值對;
命令 | 說明 |
---|---|
hset 父key 子key 子value | 將父key,增加子鍵值對,類似屬性 |
hget 父key 子key | 獲取父key,某個子key的值,獲取屬性值 |
hmset 父key 子key1 子val1 子key2 子val2 .... | 批量添加屬性 |
hmget 父key 子key1 子key... | 批量獲取屬性 |
hgetall 父key | 批量獲取屬性及值 |
hdel 父key 子key | 刪除子key屬性及值 |
hlen 父key | 返回父key中的子key個數(shù),相當于java實體的屬性個數(shù) |
hexists 父key 子key | 判斷父key中是否包含某個子key,結(jié)果為1,代表存在 |
hkeys 父key | 獲取父key中所有的子key |
hvals 父key | 獲取父key中的所有的子val |
hincrby 父key 子key 值 | 給指定的子key值增加固定的值 |
hincrbyfloat 父key 子key 值 | 給有指定key的值增加小數(shù) |
hsetnx 父key 子key 子val | 如果子key存在則失敗,如果不存在則賦值 |
1.5 有序集合-zset
在set基礎上,加一個score值。之前set是k1 v1 v2 v3,現(xiàn)在zset是k1 score1 v1 score2 v2;
命令 | 說明 |
---|---|
zadd key score1 val1 score2 val2 score3 val3 ... | 有序集合添加帶score值的元素 |
zscore key val | 獲取集合中某個值對應score值 |
zrange key 0 -1 [withscores] | zrange zset1 0 -1 ,結(jié)果為所有的值,不帶分數(shù);如:zrange zset1 0 -1 ,結(jié)果為所有的值,不帶分數(shù) |
zrange zset1 0 -1 withscores | 結(jié)果為所有的值和分數(shù) |
zrangebyscore key 開始score 結(jié)束score | 獲取score值在開始score-結(jié)束score之間的元素 |
zrangebyscore zset1 10 40 | 獲取score值在10-40之間的元素,包含10和40 |
zrangebyscore zset1 10 (40 | 不包含40值;( 的含義是不包含 |
zrangebyscore zset1 (10 (40 | 不包含10,40值 |
zrangebyscore zset1 10 50 limit 2 2 | limit 結(jié)果的起始下標,獲取的個數(shù);limit 含義是限制獲取的條數(shù),相當于mysql的分頁; |
zrem key 某score下對應的value值 | 刪除元素 |
zcard key | 獲取key對應的值的個數(shù);注意score 和 value是一個整體 |
zcount key score區(qū)間 | 獲取分值區(qū)間內(nèi)元素個數(shù) |
zrank key values值 | 獲得下標值 |
zscore key 對應value值 | 獲得value對應分數(shù) |
zrevrank key value值 | 逆序獲得對應逆序的下標值 |
zrevrange key 起始下標,結(jié)束下標 | 將之前順序進行倒序 |
zrevrangebyscore key 結(jié)束score 開始score | 根據(jù)score值輸出元素 |
zincrby key 增加分值 value值 | 給對應的值增加score值 |
2、Redis整合
2.1 spring-boot-starter-data-redis 依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
2.2 redis配置
#端口號 server: port: 8096 # redis配置 spring: redis: host: 127.0.0.1 #如果是redis遠程服務器,此處redis服務器ip地址 port: 6379 #默認端口 # database: 0 #指定redis數(shù)據(jù)庫,默認是0 # password: # 密碼有就寫,沒有就省略
2.3 SpringBoot框架自動配置的redisTemplate
2.3.1 清空數(shù)據(jù)庫
//自動裝配 SpringBoot框架自動配置的redisTemplate @Autowired private RedisTemplate<Object,Object> redisTemplate; //基于SpringBoot框架自動配置的redisTemplate,操作redis緩存 //獲取連接 RedisConnection connection = redisTemplate.getConnectionFactory().getConnection(); //清空數(shù)據(jù)庫中的所有數(shù)據(jù) log.info("清空數(shù)據(jù)庫中的所有數(shù)據(jù)"); connection.flushDb();
2.3.2 添加數(shù)據(jù)
//程序中,添加數(shù)據(jù)據(jù)到redis log.info("------ 基于SpringBoot框架自動配置的redisTemplate 添加數(shù)據(jù) ------"); redisTemplate.opsForValue().set("kh96_class_name","KGC_KH96"); redisTemplate.opsForValue().set("student_num",19);
2.3.3 獲取數(shù)據(jù)
//程序中,從redis獲取數(shù)據(jù) log.info("------ 基于SpringBoot框架自動配置的redisTemplate 獲取數(shù)據(jù) ------"); log.info("****** 根據(jù) 班級的key:{},獲取班級名稱:{} ******","kh96_class_name",redisTemplate.opsForValue().get("kh96_class_name")); log.info("****** 根據(jù) 班級的key:{},獲取班級人數(shù):{} ******","student_num",redisTemplate.opsForValue().get("student_num"));
2.3.4 修改值 (出現(xiàn)錯誤)
//程序中,基于SpringBoot框架自動配置的redisTemplate,操作redis緩存,存在問題 //場景:對班級人數(shù)進行增減操作,比如將班級人數(shù),增加10 log.info("------ 基于SpringBoot框架自動配置的redisTemplate 操作數(shù)據(jù) ------"); redisTemplate.opsForValue().increment("student_num",10); //直接報錯,會報500異常: redis.clients.jedis.exceptions.JedisDataException: ERR value is not an integer or out of range //原因,通過系統(tǒng)默認的 redisTemplate,存放key和value值時,會自動使用Object類的序列化和反序列化,導致redis中真實存放的數(shù)據(jù)不是原始值,而是序列化后的值
數(shù)據(jù)結(jié)果:
2.4 自定義redisTemplate
2.4.1 fastjson 依賴
<dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.62</version> </dependency>
2.4.2 自定義redisTemplate 配置類
//Redis自定義配置類,實現(xiàn)一個自定義序列化方式的 redisTemplate,提緩緩掉默認自動配置的 redisTemplate,實現(xiàn)String類型任意類型的value @Configuration public class RedisConfig { @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) { // 自定義redisTemplate的模板對象 RedisTemplate<String, Object> template = new RedisTemplate<>(); // 設置連接工廠 template.setConnectionFactory(redisConnectionFactory); //由于要通過程序操作遠程的redis數(shù)據(jù)庫,必須支持序列化,才可以讓程序中的數(shù)據(jù),在網(wǎng)絡中傳輸 //定義String類型的序列化方式 StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); // 定義fastjson序列化方式,可以序列化任何對象 FastJsonRedisSerializer<Object> fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class); // 需改為新的序列化方式 template.setKeySerializer(stringRedisSerializer); template.setValueSerializer(fastJsonRedisSerializer); template.setHashKeySerializer(stringRedisSerializer); template.setHashValueSerializer(fastJsonRedisSerializer); // 初始化為新的模板 template.afterPropertiesSet(); return template; } }
2.4.3 使用自定義redisTemplate 重新操作數(shù)據(jù)
//自動裝配自定義 redisTemplate @Autowired private RedisTemplate<String,Object> redisTemplate; //其他代碼不變
操作結(jié)果:
2.5 自定義redisUtils工具類
2.5.1 自定義redisUtils工具類
---> RedisUtil 工具類
2.5.2 使用自定義redisTemplate和redisUtils工具類
@GetMapping("/testRedisUtils") public String testSpringBootRedisUtils(){ //基于自定義的redisTemplate 和 RedisUtils 工具類,操作redis緩存 //程序中,添加數(shù)據(jù)據(jù)到redis log.info("------ 基于自定義的redisTemplate 和 RedisUtils 工具類 添加數(shù)據(jù) ------"); redisUtils.set("kh96_class_name_utils","KGC_KH96"); redisUtils.set("student_num_utils",19); //程序中,從redis獲取數(shù)據(jù) log.info("------ 基于自定義的redisTemplate 和 RedisUtils 工具類 獲取數(shù)據(jù) ------"); log.info("****** 根據(jù) 班級的key:{},獲取班級名稱:{} ******","kh96_class_name_utils",redisUtils.get("kh96_class_name_utils")); log.info("****** 根據(jù) 班級的key:{},獲取班級人數(shù):{} ******","student_num_utils",redisUtils.get("student_num_utils")); //程序中,基于SpringBoot框架自動配置的redisTemplate,操作redis緩存 //場景:對班級人數(shù)進行增減操作,比如姜班級人數(shù),增加10 log.info("------ 基于自定義的redisTemplate 和 RedisUtils 工具類 操作數(shù)據(jù) ------"); redisUtils.incr("student_num_utils",10); return "工具類 RedisUtils 操作 redis 成功!"; }
2.5.3 程序中如何存放對象到 redis
核心思想:一般都是姜對象轉(zhuǎn)換為json字符串,存入redis,獲取對象數(shù)據(jù),就先獲取json字符串,再轉(zhuǎn)換為對應對象即可;
@GetMapping("/testRedisUtils") public String testSpringBootRedisUtils(){ //程序中如何存放對象到 redis //核心思想:一般都是姜對象轉(zhuǎn)換為json字符串,存入redis,獲取對象數(shù)據(jù),就先獲取json字符串,再轉(zhuǎn)換為對應對象即可 //模擬用戶登錄成功后,將用戶信息存入redis中,方便后續(xù)從redis中獲取用戶信息 User loginUser = User.builder().userId(1001).userName("KH96").userTel("135012030404").build(); //直接將對象存入redis即可 log.info("------ 基于自定義的redisTemplate 和 RedisUtils 工具類 存儲對象 ------"); //自動把實體,通過fastjson的序列化方式,轉(zhuǎn)發(fā)為JSON字符串存儲 redisUtils.set(loginUser.getUserId().toString(),loginUser); //模擬獲取登錄用戶信息,直接從redis獲取存入的JSON字符串,轉(zhuǎn)換為目標用戶對象 User realUser = JSON.parseObject(redisUtils.get(loginUser.getUserId().toString()).toString(),User.class); log.info("------ 基于自定義的redisTemplate 和 RedisUtils 工具類獲取對象:{} ",realUser); return "工具類 RedisUtils 操作 redis 成功!"; }
數(shù)據(jù)結(jié)果:
到此這篇關于SpringBoot中的Redis 緩存的文章就介紹到這了,更多相關SpringBoot Redis 緩存內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
- SpringBoot整合Redis實現(xiàn)token緩存
- SpringBoot結(jié)合Redis實現(xiàn)緩存管理功能
- SpringBoot整合redis使用緩存注解詳解
- SpringBoot+MyBatis+Redis實現(xiàn)分布式緩存
- springboot使用redis注解做緩存的基本操作方式
- SpringBoot中Redis的緩存更新策略詳解
- springboot整合ehcache和redis實現(xiàn)多級緩存實戰(zhàn)案例
- SpringBoot結(jié)合Redis實現(xiàn)緩存
- SpringBoot使用Redis實現(xiàn)分布式緩存
- SpringBoot3.0集成Redis緩存的實現(xiàn)示例
相關文章
解決Android Studio安裝后運行出錯dose not...和Internal error...
這篇文章主要介紹了解決Android Studio安裝后運行出錯dose not...和Internal error...的相關資料,需要的朋友可以參考下2017-03-03SpringBoot模擬員工數(shù)據(jù)庫并實現(xiàn)增刪改查操作
這篇文章主要給大家介紹了關于SpringBoot模擬員工數(shù)據(jù)庫并實現(xiàn)增刪改查操作的相關資料,文中通過示例代碼介紹的非常詳細,對大家學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2021-09-09Java線程中synchronized和volatile關鍵字的區(qū)別詳解
這篇文章主要介紹了Java線程中synchronized和volatile關鍵字的區(qū)別詳解,synchronzied既能夠保障可見性,又能保證原子性,而volatile只能保證可見性,無法保證原子性,volatile不需要加鎖,比synchronized更輕量級,不會阻塞線程,需要的朋友可以參考下2024-01-01舉例講解Java設計模式編程中Decorator裝飾者模式的運用
這篇文章主要介紹了Java設計模式編程中Decorator裝飾者模式的運用,裝飾者模式就是給一個對象動態(tài)的添加新的功能,裝飾者和被裝飾者實現(xiàn)同一個接口,裝飾者持有被裝飾者的實例,需要的朋友可以參考下2016-05-05java序列化對象根據(jù)不同配置動態(tài)改變屬性名的方法
本文主要介紹了java序列化對象根據(jù)不同配置動態(tài)改變屬性名的方法,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-05-05Java 中文字符按Unicode排序的實現(xiàn)方法
這篇文章主要介紹了Java 中文字符按Unicode排序的實現(xiàn)方法,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2018-10-10