詳解SpringBoot使用RedisTemplate操作Redis的5種數(shù)據(jù)類型
Spring 封裝了 RedisTemplate 來操作 Redis,它支持所有的 Redis 原生的 API。在 RedisTemplate 中定義了對5種數(shù)據(jù)結(jié)構(gòu)的操作方法。
- opsForValue():操作字符串。
- opsForList():操作列表。
- opsForHash():操作哈希。
- opsForSet():操作集合。
- opsForZSet():操作有序集合。
下面通過實例來理解和應(yīng)用這些方法。這里需要特別注意的是,運行上述方法后要對數(shù)據(jù)進行清空操作,否則多次運行會導(dǎo)致數(shù)據(jù)重復(fù)操作。
(1)使用Maven添加依賴文件
在pom.xml配置信息文件中,添加Redis依賴:
我的SpringBoot版本:
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.4.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent>
添加Redis依賴:
<!-- Redis啟動器 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> <version>2.3.3.RELEASE</version> </dependency>
(2)Redis的配置
在 application.yml 配置文件中配置Redis信息:
#Spring配置 spring: #緩存管理器 cache: type: redis #Redis配置 redis: database: 0 #Redis數(shù)據(jù)庫索引(默認(rèn)為0) host: 127.0.0.1 #Redis服務(wù)器地址 port: 6379 #Redis服務(wù)器連接端口 password: #Redis服務(wù)器連接密碼(默認(rèn)為空) jedis: pool: max-active: 8 #連接池最大連接數(shù)(使用負(fù)值表示沒有限制) max-wait: -1s #連接池最大阻塞等待時間(使用負(fù)值表示沒有限制) max-idle: 8 #連接池中的最大空閑連接 min-idle: 0 #連接池中的最小空閑連接 lettuce: shutdown-timeout: 100ms #關(guān)閉超時時間,默認(rèn)值100ms
(3)Redis配置類(config層)
創(chuàng)建com.pjb.config包中,并創(chuàng)建RedisConfig類(Redis配置類),并繼承CachingConfigurerSupport類。
package com.pjb.config; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.cache.CacheManager; import org.springframework.cache.annotation.CachingConfigurerSupport; import org.springframework.cache.interceptor.KeyGenerator; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.cache.RedisCacheManager; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; import java.lang.reflect.Method; /** * Redis配置類 * @author pan_junbiao **/ @Configuration public class RedisConfig extends CachingConfigurerSupport { /** * 緩存對象集合中,緩存是以key-value形式保存的, * 當(dāng)不指定緩存的key時,SpringBoot會使用keyGenerator生成Key。 */ @Bean public KeyGenerator keyGenerator() { return new KeyGenerator() { @Override public Object generate(Object target, Method method, Object... params) { StringBuilder sb = new StringBuilder(); //類名+方法名 sb.append(target.getClass().getName()); sb.append(method.getName()); for (Object obj : params) { sb.append(obj.toString()); } return sb.toString(); } }; } /** * 緩存管理器 */ @SuppressWarnings("rawtypes") @Bean public CacheManager cacheManager(RedisConnectionFactory connectionFactory) { RedisCacheManager cacheManager = RedisCacheManager.create(connectionFactory); //設(shè)置緩存過期時間 return cacheManager; } /** * 實例化RedisTemplate對象 */ @Bean public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) { StringRedisTemplate template = new StringRedisTemplate(factory); Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(om); template.setValueSerializer(jackson2JsonRedisSerializer); template.afterPropertiesSet(); return template; } }
1、字符串(String)
字符串(String)是 Redis 最基本的數(shù)據(jù)類型。String 的一個“Key”對應(yīng)一個“Value”,即 Key-Value 鍵值對。String 是二進制安全的,可以存儲任何數(shù)據(jù)(比如圖片或序列化的對象)。值最大能存儲512MB的數(shù)據(jù)。一般用于一些復(fù)雜的計數(shù)功能的緩存。RedisTemplate 提供以下操作 String 的方法。
1.1 void set(K key, V value);V get(Object key)
具體用法見以下代碼:
/** * Redis操作字符串(String) * @author pan_junbiao **/ @SpringBootTest public class StringTest { @Autowired private RedisTemplate redisTemplate; @Test public void string1() { redisTemplate.opsForValue().set("userName","pan_junbiao的博客"); redisTemplate.opsForValue().set("blogUrl","https://blog.csdn.net/pan_junbiao"); redisTemplate.opsForValue().set("blogRemark","您好,歡迎訪問 pan_junbiao的博客"); System.out.println("用戶名稱:" + redisTemplate.opsForValue().get("userName")); System.out.println("博客地址:" + redisTemplate.opsForValue().get("blogUrl")); System.out.println("博客信息:" + redisTemplate.opsForValue().get("blogRemark")); } }
執(zhí)行結(jié)果:
1.2 void set(K key, V value, long timeout, TimeUnit unit)
以下代碼設(shè)置3s失效。3s之內(nèi)查詢有結(jié)果,3s之后查詢返回為null。具體用法見以下代碼:
@Autowired private RedisTemplate redisTemplate; @Test public void string2() { //設(shè)置的是3s失效,3s之內(nèi)查詢有結(jié)果,3s之后返回null redisTemplate.opsForValue().set("blogRemark","您好,歡迎訪問 pan_junbiao的博客",3, TimeUnit.SECONDS); try { Object s1 = redisTemplate.opsForValue().get("blogRemark"); System.out.println("博客信息:" + s1); Thread.currentThread().sleep(2000); Object s2 = redisTemplate.opsForValue().get("blogRemark"); System.out.println("博客信息:" + s2); Thread.currentThread().sleep(5000); Object s3 = redisTemplate.opsForValue().get("blogRemark"); System.out.println("博客信息:" + s3); } catch (InterruptedException ie) { ie.printStackTrace(); } }
執(zhí)行結(jié)果:
1.3 V getAndSet(K key, V value)
設(shè)置鍵的字符串,并返回其舊值。具體用法見以下代碼:
@Autowired private RedisTemplate redisTemplate; @Test public void string3() { //設(shè)置鍵的字符串并返回其舊值 redisTemplate.opsForValue().set("blogRemark","pan_junbiao的博客"); Object oldVaule = redisTemplate.opsForValue().getAndSet("blogRemark","您好,歡迎訪問 pan_junbiao的博客"); Object newVaule = redisTemplate.opsForValue().get("blogRemark"); System.out.println("舊值:" + oldVaule); System.out.println("新值:" + newVaule); }
執(zhí)行結(jié)果:
1.4 Integer append(K key, V value)
如果key已經(jīng)存在,并且是一個字符串,則該命令將該值追加到字符串的末尾。如果key不存在,則它將被創(chuàng)建并設(shè)置為空字符串,因此 append 在這種特殊情況下類似于 set。具體用法見以下代碼:
@Autowired private RedisTemplate redisTemplate; @Test public void string4() { //設(shè)置value的序列化規(guī)則,否則會報錯 redisTemplate.setValueSerializer(new StringRedisSerializer()); redisTemplate.opsForValue().append("blogRemark","您好,歡迎訪問 "); System.out.println(redisTemplate.opsForValue().get("blogRemark")); redisTemplate.opsForValue().append("blogRemark","pan_junbiao的博客"); System.out.println(redisTemplate.opsForValue().get("blogRemark")); }
執(zhí)行結(jié)果:
注意:這里一定要注意反序列化配置,否則會報錯。
1.5 Long size(K key)
返回key所對應(yīng)的value值的長度,見以下代碼:
@Autowired private RedisTemplate redisTemplate; @Test public void string5() { redisTemplate.opsForValue().set("userName","pan_junbiao的博客"); System.out.println("Value值:" + redisTemplate.opsForValue().get("userName")); System.out.println("Value值的長度:" + redisTemplate.opsForValue().size("userName")); }
執(zhí)行結(jié)果:
2、列表(List)
Redis列表是簡單的字符串列表,按照插入順序排序??梢蕴砑右粋€元素到列表的頭部(左邊)或尾部(右邊)。
使用list數(shù)據(jù)結(jié)果,可以做簡單的消息隊列的功能。還可以利用 Irange 命令,做基于Reids的分頁功能,性能極佳。
2.1 Long leftPushAll(K key, V... values);Long rightPushAll(K key, V... values)
leftPushAll方法:表示把一個數(shù)組插入列表中。
rightPushAll方法:表示向列表的最右邊批量添加元素。具體用法見以下代碼:
/** * Redis操作列表(List) * @author pan_junbiao **/ @SpringBootTest public class ListTest { @Autowired private RedisTemplate redisTemplate; @Test public void list1() { String[] user1 = new String[]{"1","pan_junbiao的博客","您好,歡迎訪問 pan_junbiao的博客"}; String[] user2 = new String[]{"2","pan_junbiao的博客","https://blog.csdn.net/pan_junbiao"}; String[] user3 = new String[]{"3","pan_junbiao的博客","您好,歡迎訪問 pan_junbiao的博客"}; redisTemplate.opsForList().rightPushAll("user1",user1); redisTemplate.opsForList().rightPushAll("user2",user2); redisTemplate.opsForList().rightPushAll("user3",user3); System.out.println(redisTemplate.opsForList().range("user1",0,-1)); System.out.println(redisTemplate.opsForList().range("user2",0,-1)); System.out.println(redisTemplate.opsForList().range("user3",0,-1)); } }
執(zhí)行結(jié)果:
2.2 Long leftPush(K key, V value);Long rightPush(K key, V value)
leftPush方法:將所有指定的值插入在鍵的列表的頭部。如果鍵不存在,則在執(zhí)行推送操作之前將其創(chuàng)建為空列表(從左邊插入)。
rightPush方法:將所有指定的值插入在鍵的列表的尾部。如果鍵不存在,則在執(zhí)行推送操作之前將其創(chuàng)建為空列表(從右邊插入)。具體用法見以下代碼:
@Autowired private RedisTemplate redisTemplate; @Test public void list2() { redisTemplate.opsForList().rightPush("userInfo",1); redisTemplate.opsForList().rightPush("userInfo","pan_junbiao的博客"); redisTemplate.opsForList().rightPush("userInfo","https://blog.csdn.net/pan_junbiao"); redisTemplate.opsForList().rightPush("userInfo","您好,歡迎訪問 pan_junbiao的博客"); System.out.println("用戶編號:" + redisTemplate.opsForList().index("userInfo",0)); System.out.println("用戶名稱:" + redisTemplate.opsForList().index("userInfo",1)); System.out.println("博客地址:" + redisTemplate.opsForList().index("userInfo",2)); System.out.println("博客信息:" + redisTemplate.opsForList().index("userInfo",3)); }
執(zhí)行結(jié)果:
2.3 Long size(K key)
返回存儲在鍵中的列表的長度。如果鍵不存在,則將其解釋為空列表,并返回0。如果key存在的值不是列表,則返回錯誤。具體用法見以下代碼:
@Autowired private RedisTemplate redisTemplate; @Test public void list3() { String[] user = new String[]{"1","pan_junbiao的博客","您好,歡迎訪問 pan_junbiao的博客"}; redisTemplate.opsForList().leftPushAll("user",user); System.out.println("列表的長度:" + redisTemplate.opsForList().size("user")); }
執(zhí)行結(jié)果:
2.4 void set(K key, long index, V value)
在列表中 index 的位置設(shè)置 value。具體用法見以下代碼:
@Autowired private RedisTemplate redisTemplate; @Test public void list4() { String[] user = new String[]{"1","pan_junbiao的博客","https://blog.csdn.net/pan_junbiao"}; redisTemplate.opsForList().rightPushAll("user",user); System.out.println(redisTemplate.opsForList().range("user",0,-1)); redisTemplate.opsForList().set("user",2,"您好,歡迎訪問 pan_junbiao的博客"); System.out.println(redisTemplate.opsForList().range("user",0,-1)); }
執(zhí)行結(jié)果:
2.5 V index(K key, long index)
根據(jù)下標(biāo)獲取列表中的值(下標(biāo)從0開始)。具體用法見以下代碼:
@Autowired private RedisTemplate redisTemplate; @Test public void list2() { redisTemplate.opsForList().rightPush("userInfo",1); redisTemplate.opsForList().rightPush("userInfo","pan_junbiao的博客"); redisTemplate.opsForList().rightPush("userInfo","https://blog.csdn.net/pan_junbiao"); redisTemplate.opsForList().rightPush("userInfo","您好,歡迎訪問 pan_junbiao的博客"); System.out.println("用戶編號:" + redisTemplate.opsForList().index("userInfo",0)); System.out.println("用戶名稱:" + redisTemplate.opsForList().index("userInfo",1)); System.out.println("博客地址:" + redisTemplate.opsForList().index("userInfo",2)); System.out.println("博客信息:" + redisTemplate.opsForList().index("userInfo",3)); }
執(zhí)行結(jié)果:
2.6 Long remove(K key, long count, Object value)
從存儲在鍵中的列表,刪除給定“count”值的元素的第1個計數(shù)事件。其中,參數(shù)count的含義如下:
- count=0:刪除等于value的所有元素。
- count>0:刪除等于從頭到尾移動的值的元素。
- count<0:刪除等于從尾到頭移動的值的元素。
以下代碼用于刪除列表中第一次出現(xiàn)的值:
@Autowired private RedisTemplate redisTemplate; @Test public void list5() { String[] user = new String[]{"1","pan_junbiao的博客","您好,歡迎訪問 pan_junbiao的博客"}; redisTemplate.opsForList().rightPushAll("user",user); System.out.println(redisTemplate.opsForList().range("user",0,-1)); //將刪除列表中第一次出現(xiàn)的pan_junbiao的博客 redisTemplate.opsForList().remove("user",1,"pan_junbiao的博客"); System.out.println(redisTemplate.opsForList().range("user",0,-1)); }
執(zhí)行結(jié)果:
2.7 V leftPop(K key);V rightPop(K key)
leftPop方法:彈出最左邊的元素,彈出之后該值在列表中將不復(fù)存在。
rightPop方法:彈出最右邊的元素,彈出之后該值在列表中將不復(fù)存在。具體用法見以下代碼:
@Autowired private RedisTemplate redisTemplate; @Test public void list6() { String[] user = new String[]{"1","pan_junbiao的博客","您好,歡迎訪問 pan_junbiao的博客"}; redisTemplate.opsForList().rightPushAll("user",user); System.out.println(redisTemplate.opsForList().range("user",0,-1)); //彈出最右邊的元素,彈出之后該值在列表中將不復(fù)存在 System.out.println(redisTemplate.opsForList().rightPop("user")); System.out.println(redisTemplate.opsForList().range("user",0,-1)); }
執(zhí)行結(jié)果:
3、哈希(Hash)
Redis 中的 hash(哈希)是一個 string 類型的 field 和 value 的映射表,hash 特別適合用于存儲對象。value 中存放的是結(jié)構(gòu)化的對象。利用這樣數(shù)據(jù)結(jié)果,可以方便地操作其中的某個字段。比如在“單點登錄”時,可以用這種數(shù)據(jù)結(jié)構(gòu)存儲用戶信息。以 CookieId 作為 key,設(shè)置30分鐘為緩存過期時間,能很好地模擬出類似 Session 的效果。
3.1 void putAll(H key, Map<? extends HK, ? extends HV> m);Map<HK, HV> entries(H key)
putAll方法:用 m 中提供的多個散列字段設(shè)置到 key 對應(yīng)的散列表中。
entries方法:根據(jù)密鑰獲取整個散列存儲。具體用法見以下代碼:
/** * Redis操作哈希(Hash) * @author pan_junbiao **/ @SpringBootTest public class HashTest { @Autowired private RedisTemplate redisTemplate; @Test public void hash1() { Map<String,Object> userMap = new HashMap<>(); userMap.put("userName","pan_junbiao的博客"); userMap.put("blogRemark","您好,歡迎訪問 pan_junbiao的博客"); redisTemplate.opsForHash().putAll("userHash",userMap); System.out.println(redisTemplate.opsForHash().entries("userHash")); } }
執(zhí)行結(jié)果:
3.2 void put(H key, HK hashKey, HV value);HV get(H key, Object hashKey)
put方法:設(shè)置 hashKey 的值。
get方法:從鍵中的散列獲取給定 hashKey 的值。具體用法見以下代碼:
@Autowired private RedisTemplate redisTemplate; @Test public void hash2() { redisTemplate.opsForHash().put("userHash","userName","pan_junbiao的博客"); redisTemplate.opsForHash().put("userHash","blogUrl","https://blog.csdn.net/pan_junbiao"); redisTemplate.opsForHash().put("userHash","blogRemark","您好,歡迎訪問 pan_junbiao的博客"); System.out.println("用戶名稱:" + redisTemplate.opsForHash().get("userHash","userName")); System.out.println("博客地址:" + redisTemplate.opsForHash().get("userHash","blogUrl")); System.out.println("博客信息:" + redisTemplate.opsForHash().get("userHash","blogRemark")); }
執(zhí)行結(jié)果:
3.3 List<HV> values(H key);Set<HK> keys(H key)
values方法:根據(jù)密鑰獲取整個散列存儲的值。
keys方法:根據(jù)密鑰獲取整個散列存儲的鍵。具體用法見以下代碼:
@Autowired private RedisTemplate redisTemplate; @Test public void hash3() { redisTemplate.opsForHash().put("userHash","userName","pan_junbiao的博客"); redisTemplate.opsForHash().put("userHash","blogRemark","您好,歡迎訪問 pan_junbiao的博客"); System.out.println("散列存儲的值:" + redisTemplate.opsForHash().values("userHash")); System.out.println("散列存儲的鍵:" + redisTemplate.opsForHash().keys("userHash")); }
執(zhí)行結(jié)果:
3.4 Boolean hasKey(H key, Object hashKey);Long size(H key)
hasKey方法:確定 hashKey 是否存在。
size方法:獲取 key 所對應(yīng)的散列表的大小個數(shù)。具體用法見以下代碼:
@Autowired private RedisTemplate redisTemplate; @Test public void hash4() { redisTemplate.opsForHash().put("userHash","userName","pan_junbiao的博客"); redisTemplate.opsForHash().put("userHash","blogUrl","https://blog.csdn.net/pan_junbiao"); redisTemplate.opsForHash().put("userHash","blogRemark","您好,歡迎訪問 pan_junbiao的博客"); System.out.println(redisTemplate.opsForHash().hasKey("userHash","userName")); System.out.println(redisTemplate.opsForHash().hasKey("userHash","age")); System.out.println(redisTemplate.opsForHash().size("userHash")); }
執(zhí)行結(jié)果:
3.5 Long delete(H key, Object... hashKeys)
刪除給定的 hashKeys。具體用法見以下代碼:
@Autowired private RedisTemplate redisTemplate; @Test public void hash5() { redisTemplate.opsForHash().put("userHash","userName","pan_junbiao的博客"); redisTemplate.opsForHash().put("userHash","blogRemark","您好,歡迎訪問 pan_junbiao的博客"); System.out.println(redisTemplate.opsForHash().delete("userHash","blogRemark")); System.out.println(redisTemplate.opsForHash().entries("userHash")); }
執(zhí)行結(jié)果:
4、集合(Set)
set 是存放不重復(fù)值的集合。利用 set 可以做全局去重復(fù)的功能。還可以進行交集、并集、差集等操作,也可用來實現(xiàn)計算共同喜好、全部的喜好、自己獨有的喜好等功能。
Redis 的 set 是 string 類型的無序集合,通過散列表實現(xiàn)。
4.1 Long add(K key, V... values);Set<V> members(K key)
add方法:在無序集合中添加元素,返回添加個數(shù);如果存在重復(fù)的則不進行添加。
members方法:返回集合中的所有成員。具體用法見以下代碼:
/** * Redis操作集合(Set) * @author pan_junbiao **/ @SpringBootTest public class SetTest { @Autowired private RedisTemplate redisTemplate; @Test public void set1() { String[] citys = new String[]{"北京","上海","廣州","深圳"}; System.out.println(redisTemplate.opsForSet().add("citySet",citys)); System.out.println(redisTemplate.opsForSet().add("citySet","香港","澳門","臺灣")); //返回集合中的所有元素 System.out.println(redisTemplate.opsForSet().members("citySet")); } }
執(zhí)行結(jié)果:
4.2 Long remove(K key, Object... values)
移除集合中一個或多個成員。具體用法見以下代碼:
@Autowired private RedisTemplate redisTemplate; @Test public void set2() { String[] citys = new String[]{"北京","上海","廣州","深圳"}; System.out.println(redisTemplate.opsForSet().add("citySet",citys)); System.out.println(redisTemplate.opsForSet().remove("citySet",citys)); }
執(zhí)行結(jié)果:
4.3 V pop(K key)
移除并返回集合中的一個隨機元素。具體用法見以下代碼:
@Autowired private RedisTemplate redisTemplate; @Test public void set3() { String[] citys = new String[]{"北京","上海","廣州","深圳"}; System.out.println(redisTemplate.opsForSet().add("citySet",citys)); System.out.println(redisTemplate.opsForSet().pop("citySet")); System.out.println(redisTemplate.opsForSet().members("citySet")); }
執(zhí)行結(jié)果:
4.4 Boolean move(K key, V value, K destKey)
將 member 元素移動。具體用法見以下代碼:
@Autowired private RedisTemplate redisTemplate; @Test public void set4() { String[] citys = new String[]{"北京","上海","廣州","深圳"}; System.out.println(redisTemplate.opsForSet().add("citySet",citys)); System.out.println(redisTemplate.opsForSet().move("citySet","深圳","citySet2")); System.out.println(redisTemplate.opsForSet().members("citySet")); System.out.println(redisTemplate.opsForSet().members("citySet2")); }
執(zhí)行結(jié)果:
4.5 Cursor<V> scan(K key, ScanOptions options)
用于遍歷 Set。具體用法見以下代碼:
@Autowired private RedisTemplate redisTemplate; @Test public void set5() { String[] citys = new String[]{"北京","上海","廣州","深圳"}; System.out.println(redisTemplate.opsForSet().add("citySet",citys)); Cursor<Object> cursor = redisTemplate.opsForSet().scan("citySet", ScanOptions.NONE); while(cursor.hasNext()) { System.out.println(cursor.next()); } }
執(zhí)行結(jié)果:
4.6 交集、并集、差集
- Set<V> intersect(K key1, K key2)方法、Long intersectAndStore(K key1, K key2, K destKey)方法:交集。
- Set<V> union(K key1, K key2)方法、Long unionAndStore(K key1, K key2, K destKey)方法:并集。
- Set<V> difference(K key1, K key2)方法、Long differenceAndStore(K key1, K key2, K destKey)方法:差集。
具體用法見以下代碼:
@Autowired private RedisTemplate redisTemplate; @Test public void set6() { String[] city1 = new String[]{"北京", "上海", "廣州", "深圳", "昆明"}; String[] city2 = new String[]{"北京", "深圳", "昆明", "成都"}; System.out.println(redisTemplate.opsForSet().add("citySet1", city1)); System.out.println(redisTemplate.opsForSet().add("citySet2", city2)); //返回集合中的所有元素 System.out.println("城市集合1:" + redisTemplate.opsForSet().members("citySet1")); System.out.println("城市集合2:" + redisTemplate.opsForSet().members("citySet2")); //求交集、并集、差集(方式一) System.out.println("求交集、并集、差集(方式一):"); System.out.println("交集:" + redisTemplate.opsForSet().intersect("citySet1","citySet2")); System.out.println("并集:" + redisTemplate.opsForSet().union("citySet1","citySet2")); System.out.println("差集:" + redisTemplate.opsForSet().difference("citySet1","citySet2")); //求交集、并集、差集(方式二) redisTemplate.opsForSet().intersectAndStore("citySet1","citySet2", "intersectCity"); redisTemplate.opsForSet().unionAndStore("citySet1","citySet2", "unionCity"); redisTemplate.opsForSet().differenceAndStore("citySet1","citySet2", "differenceCity"); System.out.println("求交集、并集、差集(方式二):"); System.out.println("交集:" + redisTemplate.opsForSet().members("intersectCity")); System.out.println("并集:" + redisTemplate.opsForSet().members("unionCity")); System.out.println("差集:" + redisTemplate.opsForSet().members("differenceCity")); }
執(zhí)行結(jié)果:
5、有序集合(Sorted Set)
zset(Sorted Set 有序集合)也是 string 類型元素的集合,且不允許重復(fù)的成員。每個元素都會關(guān)聯(lián)一個 double 類型的分?jǐn)?shù)??梢酝ㄟ^分?jǐn)?shù)將該集合中的成員從小到大進行排序。
zset 的成員是唯一的,但權(quán)重參數(shù)分?jǐn)?shù)(score)卻可以重復(fù)。集合中的元素能夠按 score 進行排列。它可以用來做排行榜應(yīng)用、取TOP/N、延時任務(wù)、范圍查找等。
5.1 Long add(K key, Set<ZSetOperations.TypedTuple<V>> tuples)
增加一個有序集合。具體用法見以下代碼:
import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.redis.core.DefaultTypedTuple; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.ZSetOperations; import java.util.HashSet; import java.util.Set; /** * Redis操作有序集合(Sorted Set) * @author pan_junbiao **/ @SpringBootTest public class SortedSetTest { @Autowired private RedisTemplate redisTemplate; @Test public void Zset1() { ZSetOperations.TypedTuple<String> objectTypedTuple1 = new DefaultTypedTuple<>("pan_junbiao的博客_01",9.6); ZSetOperations.TypedTuple<String> objectTypedTuple2 = new DefaultTypedTuple<>("pan_junbiao的博客_02",1.5); ZSetOperations.TypedTuple<String> objectTypedTuple3 = new DefaultTypedTuple<>("pan_junbiao的博客_03",7.4); Set<ZSetOperations.TypedTuple<String>> typles = new HashSet<ZSetOperations.TypedTuple<String>>(); typles.add(objectTypedTuple1); typles.add(objectTypedTuple2); typles.add(objectTypedTuple3); System.out.println(redisTemplate.opsForZSet().add("typles",typles)); System.out.println(redisTemplate.opsForZSet().range("typles",0,-1)); } }
執(zhí)行結(jié)果:
5.2 Boolean add(K key, V value, double score)
新增一個有序集合,存在的話為false,不存在的話為true。具體用法見以下代碼:
@Autowired private RedisTemplate redisTemplate; @Test public void Zset2() { System.out.println(redisTemplate.opsForZSet().add("zset2", "pan_junbiao的博客_01", 9.6)); System.out.println(redisTemplate.opsForZSet().add("zset2", "pan_junbiao的博客_01", 9.6)); }
執(zhí)行結(jié)果:
5.3 Long remove(K key, Object... values)
從有序集合中移除一個或者多個元素。具體用法見以下代碼:
@Autowired private RedisTemplate redisTemplate; @Test public void Zset3() { System.out.println(redisTemplate.opsForZSet().add("zset3", "pan_junbiao的博客_01", 1.0)); System.out.println(redisTemplate.opsForZSet().add("zset3", "pan_junbiao的博客_02", 1.0)); System.out.println(redisTemplate.opsForZSet().range("zset3", 0, -1)); System.out.println(redisTemplate.opsForZSet().remove("zset3", "pan_junbiao的博客_02")); System.out.println(redisTemplate.opsForZSet().range("zset3", 0, -1)); }
執(zhí)行結(jié)果:
5.4 Long rank(K key, Object value)
返回有序集中指定成員的排名,其中有序集成員按分?jǐn)?shù)值遞增(從小到大)順序排列。具體用法見以下代碼:
@Autowired private RedisTemplate redisTemplate; @Test public void Zset4() { System.out.println(redisTemplate.opsForZSet().add("zset4", "pan_junbiao的博客_01",9.6)); System.out.println(redisTemplate.opsForZSet().add("zset4", "pan_junbiao的博客_02",1.5)); System.out.println(redisTemplate.opsForZSet().add("zset4", "pan_junbiao的博客_03",7.4)); System.out.println(redisTemplate.opsForZSet().range("zset4", 0, -1)); System.out.println(redisTemplate.opsForZSet().rank("zset4", "pan_junbiao的博客_02")); }
執(zhí)行結(jié)果:
注意:結(jié)果中的0表示第一(最?。?。
5.5 Set<V> range(K key, long start, long end);Set<V> rangeByScore(K key, double score1, double score2)
range方法:通過索引區(qū)間返回有序集合成指定區(qū)間內(nèi)的成員,其中有序集成員按分?jǐn)?shù)值遞增(從小到大)順序排列。
rangeByScore方法:通過分?jǐn)?shù)區(qū)間返回有序集合成指定區(qū)間內(nèi)的成員,其中有序集成員按分?jǐn)?shù)值遞增(從小到大)順序排列。
具體用法見以下代碼:
@Autowired private RedisTemplate redisTemplate; @Test public void Zset5() { ZSetOperations.TypedTuple<String> objectTypedTuple1 = new DefaultTypedTuple<>("pan_junbiao的博客_01",9.6); ZSetOperations.TypedTuple<String> objectTypedTuple2 = new DefaultTypedTuple<>("pan_junbiao的博客_02",1.5); ZSetOperations.TypedTuple<String> objectTypedTuple3 = new DefaultTypedTuple<>("pan_junbiao的博客_03",7.4); Set<ZSetOperations.TypedTuple<String>> typles = new HashSet<ZSetOperations.TypedTuple<String>>(); typles.add(objectTypedTuple1); typles.add(objectTypedTuple2); typles.add(objectTypedTuple3); System.out.println(redisTemplate.opsForZSet().add("zset5",typles)); System.out.println(redisTemplate.opsForZSet().range("zset5",0,-1)); System.out.println(redisTemplate.opsForZSet().rangeByScore("zset5", 0, 8)); }
執(zhí)行結(jié)果:
5.6 Long count(K key, double score1, double score2);Long size(K key)
count方法:通過分?jǐn)?shù)返回有序集合指定區(qū)間內(nèi)的成員個數(shù)。
size方法:獲取有序集合的成員數(shù)。
具體用法見以下代碼:
@Autowired private RedisTemplate redisTemplate; @Test public void Zset6() { ZSetOperations.TypedTuple<String> objectTypedTuple1 = new DefaultTypedTuple<>("pan_junbiao的博客_01",9.6); ZSetOperations.TypedTuple<String> objectTypedTuple2 = new DefaultTypedTuple<>("pan_junbiao的博客_02",1.5); ZSetOperations.TypedTuple<String> objectTypedTuple3 = new DefaultTypedTuple<>("pan_junbiao的博客_03",7.4); Set<ZSetOperations.TypedTuple<String>> typles = new HashSet<ZSetOperations.TypedTuple<String>>(); typles.add(objectTypedTuple1); typles.add(objectTypedTuple2); typles.add(objectTypedTuple3); redisTemplate.opsForZSet().add("zset6", typles); System.out.println("分?jǐn)?shù)在0至8區(qū)間內(nèi)的成員個數(shù):" + redisTemplate.opsForZSet().count("zset6", 0, 8)); System.out.println("有序集合的成員數(shù):" + redisTemplate.opsForZSet().size("zset6")); }
執(zhí)行結(jié)果:
5.7 Double score(K key, Object o)
獲取指定成員的score值。具體用法見以下代碼:
@Test public void Zset7() { redisTemplate.opsForZSet().add("zset7", "pan_junbiao的博客_01", 9.6); redisTemplate.opsForZSet().add("zset7", "pan_junbiao的博客_02", 1.5); redisTemplate.opsForZSet().add("zset7", "pan_junbiao的博客_03", 7.4); System.out.println("pan_junbiao的博客_01的分?jǐn)?shù):" + redisTemplate.opsForZSet().score("zset7", "pan_junbiao的博客_01")); System.out.println("pan_junbiao的博客_02的分?jǐn)?shù):" + redisTemplate.opsForZSet().score("zset7", "pan_junbiao的博客_02")); System.out.println("pan_junbiao的博客_03的分?jǐn)?shù):" + redisTemplate.opsForZSet().score("zset7", "pan_junbiao的博客_03")); }
執(zhí)行結(jié)果:
5.8 Long removeRange(K key, long start, long end)
移除指定索引位置的成員,有序集合成員按照分?jǐn)?shù)值遞增(從小到大)順序排列。具體用法見以下代碼:
@Autowired private RedisTemplate redisTemplate; @Test public void Zset8() { ZSetOperations.TypedTuple<String> objectTypedTuple1 = new DefaultTypedTuple<>("pan_junbiao的博客_01",9.6); ZSetOperations.TypedTuple<String> objectTypedTuple2 = new DefaultTypedTuple<>("pan_junbiao的博客_02",1.5); ZSetOperations.TypedTuple<String> objectTypedTuple3 = new DefaultTypedTuple<>("pan_junbiao的博客_03",7.4); Set<ZSetOperations.TypedTuple<String>> tuples = new HashSet<ZSetOperations.TypedTuple<String>>(); tuples.add(objectTypedTuple1); tuples.add(objectTypedTuple2); tuples.add(objectTypedTuple3); System.out.println(redisTemplate.opsForZSet().add("zset8", tuples)); System.out.println(redisTemplate.opsForZSet().range("zset8", 0, -1)); System.out.println(redisTemplate.opsForZSet().removeRange("zset8", 1, 5)); System.out.println(redisTemplate.opsForZSet().range("zset8", 0, -1)); }
執(zhí)行結(jié)果:
5.9 Cursor<ZSetOperations.TypedTuple<V>> scan(K key, ScanOptions options)
遍歷 zset。具體用法見以下代碼:
@Autowired private RedisTemplate redisTemplate; @Test public void Zset9() { ZSetOperations.TypedTuple<String> objectTypedTuple1 = new DefaultTypedTuple<>("pan_junbiao的博客_01",9.6); ZSetOperations.TypedTuple<String> objectTypedTuple2 = new DefaultTypedTuple<>("pan_junbiao的博客_02",1.5); ZSetOperations.TypedTuple<String> objectTypedTuple3 = new DefaultTypedTuple<>("pan_junbiao的博客_03",7.4); Set<ZSetOperations.TypedTuple<String>> tuples = new HashSet<ZSetOperations.TypedTuple<String>>(); tuples.add(objectTypedTuple1); tuples.add(objectTypedTuple2); tuples.add(objectTypedTuple3); System.out.println(redisTemplate.opsForZSet().add("zset9", tuples)); Cursor<ZSetOperations.TypedTuple<Object>> cursor = redisTemplate.opsForZSet().scan("zset9", ScanOptions.NONE); while (cursor.hasNext()) { ZSetOperations.TypedTuple<Object> item = cursor.next(); System.out.println(item.getValue() + " 的分?jǐn)?shù)值:" + item.getScore()); } }
執(zhí)行結(jié)果:
到此這篇關(guān)于詳解SpringBoot使用RedisTemplate操作Redis的5種數(shù)據(jù)類型的文章就介紹到這了,更多相關(guān)SpringBoot使用RedisTemplate操作Redis內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot整合Redis使用RedisTemplate和StringRedisTemplate
- springboot使用redisTemplate操作lua腳本
- SpringBoot整合Redis使用@Cacheable和RedisTemplate
- springboot使用redisRepository和redistemplate操作redis的過程解析
- Redis6搭建集群并在SpringBoot中使用RedisTemplate的實現(xiàn)
- SpringBoot使用RedisTemplate.delete刪除指定key失敗的解決辦法
- Spring Boot單元測試中使用mockito框架mock掉整個RedisTemplate的示例
- Spring Boot中RedisTemplate的使用示例詳解
相關(guān)文章
Java將json字符串轉(zhuǎn)換為數(shù)組的幾種方法
在Java開發(fā)中,經(jīng)常會遇到將json字符串轉(zhuǎn)換為數(shù)組的需求,本文主要介紹了Java將json字符串轉(zhuǎn)換為數(shù)組的幾種方法,具有一定的參考價值,感興趣的可以了解一下2024-01-01SpringBoot中使用Quartz設(shè)置定時任務(wù)的實例詳解
Quartz是OpenSymphony開源組織在任務(wù)調(diào)度領(lǐng)域的一個開源項目,完全基于 Java 實現(xiàn),本文小編給大家介紹了SpringBoot中如何使用Quartz設(shè)置定時任務(wù),文中通過代碼示例給大家講解的非常詳細(xì),需要的朋友可以參考下2023-12-12java?使用BeanFactory實現(xiàn)service與dao層解耦合詳解
這篇文章主要介紹了java?使用BeanFactory實現(xiàn)service與dao層解耦合詳解,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-12-12關(guān)于Java鎖性能提高(鎖升級)機制的總結(jié)
這篇文章主要介紹了關(guān)于Java鎖性能提高(鎖升級)機制的總結(jié),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-05-05spring-boot-autoconfigure模塊用法詳解
autoconfigure就是自動配置的意思,spring-boot通過spring-boot-autoconfigure體現(xiàn)了"約定優(yōu)于配置"這一設(shè)計原則,而spring-boot-autoconfigure主要用到了spring.factories和幾個常用的注解條件來實現(xiàn)自動配置,思路很清晰也很簡單,感興趣的朋友跟隨小編一起看看吧2022-11-11詳解SpringBoot中使用JPA作為數(shù)據(jù)持久化框架
這篇文章主要介紹了SpringBoot中使用JPA作為數(shù)據(jù)持久化框架的相關(guān)知識,本文通過示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-03-03