目錄
RedisTemplate 概述
1、Redis 是一個緩存、消息代理和功能豐富的鍵值存儲。Spring Boot 爲 Lettuce 和 Jedis 客戶端庫提供基本的自動配置,併爲 Spring Data Redis 提供抽象。官網傳送。
2、spring-boot-starter-data-redis 啓動器,整合了需要的依賴項,默認情況下,它使用 Lettuce 作爲客戶端。這個啓動器同時處理傳統應用程序和反應性應用程序(reactive applications)。
3、官方還提供了一個 spring-boot-starter-data-redis-reactive 啓動器,用於與具有 reactive 支持的其他存儲保持一致。
4、可以像注入任何其他 Spring Bean 一樣注入一個自動配置的 RedisConnectionFactory、StringRedisTemplate 或普通的 RedisTemplate 實例。class StringRedisTemplate extends RedisTemplate<String, String>
5、默認情況下,Redis 實例嘗試連接本地主機(localhost)端口爲 6379 的 Redis 服務器,默認使用空密碼,連接 0 號數據庫:
REDIS (RedisProperties)
spring.redis.cluster.max-redirects= # Maximum number of redirects to follow when executing commands across the cluster.
spring.redis.cluster.nodes= # Comma-separated list of "host:port" pairs to bootstrap from.
spring.redis.database=0 # Database index used by the connection factory.
spring.redis.url= # Connection URL. Overrides host, port, and password. User is ignored. Example: redis://user:[email protected]:6379
spring.redis.host=localhost # Redis server host.
spring.redis.jedis.pool.max-active=8 # Maximum number of connections that can be allocated by the pool at a given time. Use a negative value for no limit.
spring.redis.jedis.pool.max-idle=8 # Maximum number of "idle" connections in the pool. Use a negative value to indicate an unlimited number of idle connections.
spring.redis.jedis.pool.max-wait=-1ms # Maximum amount of time a connection allocation should block before throwing an exception when the pool is exhausted. Use a negative value to block indefinitely.
spring.redis.jedis.pool.min-idle=0 # Target for the minimum number of idle connections to maintain in the pool. This setting only has an effect if it is positive.
spring.redis.lettuce.pool.max-active=8 # Maximum number of connections that can be allocated by the pool at a given time. Use a negative value for no limit.
spring.redis.lettuce.pool.max-idle=8 # Maximum number of "idle" connections in the pool. Use a negative value to indicate an unlimited number of idle connections.
spring.redis.lettuce.pool.max-wait=-1ms # Maximum amount of time a connection allocation should block before throwing an exception when the pool is exhausted. Use a negative value to block indefinitely.
spring.redis.lettuce.pool.min-idle=0 # Target for the minimum number of idle connections to maintain in the pool. This setting only has an effect if it is positive.
spring.redis.lettuce.shutdown-timeout=100ms # Shutdown timeout.
spring.redis.password= # Login password of the redis server.
spring.redis.port=6379 # Redis server port.
spring.redis.sentinel.master= # Name of the Redis server.
spring.redis.sentinel.nodes= # Comma-separated list of "host:port" pairs.
spring.redis.ssl=false # Whether to enable SSL support.
spring.redis.timeout= # Connection timeout.
6、可以實現 LettuceClientConfigurationBuilderCustomizer 接口,以實現更高級的定製。如果使用的是 Jedis 客戶端,則實現 JedisClientConfigurationBuilderCustomizer 接口。
RedisTemplate 默認自己的序列化速度並不理想,實際生產中遇到一次需要將數據庫查出來的一個 List 對象放到 Redis 中,當時數據量達到 20 萬行,結果 put 的時間長達 6、7 秒,然後當使用 alibaba 的 fastjson 先將 List 對象序列化爲字符串,然後在 put 到緩存,此時時間降到了 100 毫秒內,而 fastjson 序列化同樣非常之快。取值時,同樣將取出的字符串使用 fastjosn 反序列化成 List 即可。
7、Redis 三個客戶端框架:Jedis、Redisson、Lettuce 對比。
RedisTemplate 使用
RedisAutoConfiguration 中已經自動將 RedisTemplate 添加到了容器中,直接獲取使用即可.
1、RedisTemplate 對 lettuce 與 Jedis 封裝之後,使用更加簡單,如同使用 JDBCTemplate 對 JDBC 進行了封裝。封裝之後不需要再關心打開與關閉連接等繁瑣的操作,而且它提供性能更好的連接池等。
2、本文環境 Spring Boot 2.1.3 + Java JDK 1.8,pom.xml 文件中導入依賴,然後在需要地方直接注入 RedisTemplate 或者 StringRedisTemplate 使用即可:
<!--Spring Boot redis 啓動器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--如果配置文件中配置了 redis 的連接池,則需要導入commons-pool2依賴 -->
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-pool2 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.7.0</version>
</dependency>
3、全局配置文件配置 Redis 如下,連接本地沒有設置密碼的 Redis 服務器:
#Redis 配置,以下除了 timeout 外全部爲默認配置.
spring:
redis:
host: localhost
port: 6379
database: 0
password:
timeout: 10000
lettuce:
pool:
max-active: 8
max-idle: 8
min-idle: 0
max-wait: -1ms
3、Redis 支持五種數據類型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合),RedisTemplate 分別提供了對應的 API 進行操作它們。
字符串(String)
org.springframework.data.redis.core.ValueOperations 處理 String 類型數據:
方法 | 描述 |
---|---|
set(K key, V value) | 存儲到 redis。key 已經存在時,覆蓋舊值,不存在時新增。key、value 不能爲 null |
set(K key, V value, long timeout, TimeUnit unit) | 設置失效時間爲指定時間。超過後 key 會被移除 |
set(K key, V value, Duration timeout) | 設置超時時間,Duration 是 Jdk 8 的 API。超過指定時間後,key 被移除 |
set(K key, V value, long offset) | 覆寫(overwrite)給定 key 所儲存的字符串值,從偏移量 offset 開始 |
get(Object key) | 獲取指定 key 的 value,key 不存在時,返回 null。key 不能 null |
getAndSet(K key, V value) | 獲取 key 的舊值,並賦值新的 value。key 不能 null |
get(K key, long start, long end) | 獲取指定 key 指定範圍的字符串 [start,end],從索引 0 開始。key 不能 null |
append(K key, String value) | 將新的 value 追加到 key 的舊值尾部,key 不存在時,自動新建。key 不能爲 null。 |
Long size(K key) | 獲取 key 的 value 的長度,key 不存在時,返回 0。key 不能爲 null。 |
Boolean setIfAbsent(K key, V value) | 如果 key 不存在,則新增,否則不改變原來的值。其餘重載方法與 set 方法對應。key、value 不能爲 null。 |
Boolean setIfPresent(K key, V value, Duration timeout) | key 存在時,才修改它的值,否則不新增,與 setIfAbsent 相反。 |
Long increment(K key) | 將存儲爲字符串值的整數值增加1,並返回結果。key 不存在時自動新增 |
Long increment(K key, long delta) | 將存儲爲字符串值的整數值增加 delta,並返回結果。key 不存在時自動新增。delta 爲負數時,做減法 |
Double increment(K key, double delta) | 將存儲爲字符串值的小數值增加 delta,並返回結果。key 不存在時自動新增 |
Long decrement(K key) | 將存儲爲字符串的整數值減1,key 不存在時自動創建 |
Long decrement(K key, long delta) | 減去指定的數值,key 不存在時自動創建。delta |
List multiGet(Collection keys) | 同時獲取多個 key 的值,按請求的 key 的順序返回對應的 value,key 不存在的返回 null。 |
multiSet(Map<? extends K, ? extends V> map) | 同時存儲多個 key-value |
Boolean multiSetIfAbsent(Map<? extends K, ? extends V> map) | 當 key 不存在時新增,否則進行操作。 |
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.*;
import org.springframework.test.context.junit4.SpringRunner;
import javax.annotation.Resource;
import java.time.Duration;
import java.util.*;
import java.util.concurrent.TimeUnit;
@RunWith(SpringRunner.class)
@SpringBootTest
public class RedisStuWebApplicationTests {
//注入 RedisTemplate 或者 StringRedisTemplate 其中一個即可,前者是後者的父類,它們都已經默認在 Spring 容器中了。
//org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration 中已經自動將 RedisTemplate 添加到了容器中,直接獲取使用即可.
@Resource
private RedisTemplate redisTemplate;
@Resource
private StringRedisTemplate stringRedisTemplate;
//org.springframework.data.redis.core.ValueOperations 處理 String 類型數據
@Test
public void test1() {
redisTemplate.getConnectionFactory().getConnection().flushAll();//清空 redis 所有緩存的數據。
ValueOperations<String, String> valueOperations = stringRedisTemplate.opsForValue();
valueOperations.set("user.name", "張無忌 ");//添加值
valueOperations.set("upload.process", "65", 60, TimeUnit.SECONDS);//添加值,失效時間60秒
valueOperations.set("user.status", "online", Duration.ofSeconds(20));//添加值,失效時間20秒
String user_name = valueOperations.get("user.name");//取值
String upload_process = valueOperations.get("upload.process");//取值
String user_status = valueOperations.get("user.status");//取值
String user_status2 = valueOperations.get("user.status", 2, 4);//取值,截取子符串
//輸出:張無忌 , 65, online, lin
System.out.println(user_name + ", " + upload_process + ", " + user_status + ", " + user_status2);
Integer hello = valueOperations.append("user.hit", "Hello");//爲末尾追加值
String hit1 = valueOperations.get("user.hit");//取值
Integer hello2 = valueOperations.append("user.hit", " World");//爲末尾追加值
String hit2 = valueOperations.get("user.hit");//取值
Long size = valueOperations.size("user.hit");//字符串的長度
//輸出:5 - Hello, 11 - Hello World
System.out.println(hello + " - " + hit1 + ", " + hello2 + " - " + hit2 + ", " + size);
//key 不存在時,才進行添加
Boolean aBoolean1 = valueOperations.setIfAbsent("name", "三豐", 60, TimeUnit.SECONDS);
Boolean aBoolean2 = valueOperations.setIfAbsent("name", "四喜", 60, TimeUnit.SECONDS);
System.out.println(aBoolean1 + ", " + aBoolean2 + ", " + valueOperations.get("name"));//輸出:true, false, 三豐
//key 存在時,才進行添加
Boolean age1 = valueOperations.setIfPresent("age", "45", Duration.ofSeconds(60));
valueOperations.set("age", "35");
Boolean age2 = valueOperations.setIfPresent("age", "55", Duration.ofSeconds(60));
System.out.println(age1 + ", " + age2 + ", " + valueOperations.get("age"));//輸出:false, true, 55
valueOperations.set("l1", "1", Duration.ofSeconds(60));
valueOperations.set("d1", "3.14", Duration.ofSeconds(60));
valueOperations.set("total", "100", Duration.ofSeconds(60));
Long count1 = valueOperations.increment("l1");//數值做加法
Long count2 = valueOperations.increment("l1", 10L);
Double d1 = valueOperations.increment("d1", 40.00);
Long total1 = valueOperations.decrement("total");//數值做減法
Long total2 = valueOperations.decrement("total2", 35);
System.out.println(count1 + ", " + count2 + ", " + d1 + ", " + total1 + ", " + total2);//輸出:2, 12, 43.14, 99, 64
List<String> keyList = new ArrayList<>();
keyList.add("l1");
keyList.add("d1");
keyList.add("f1");
List<String> list = valueOperations.multiGet(keyList);//同時獲取多個 key 的 value
System.out.println(list);//[12, 43.140000000000001, null]
Map<String, String> dataMap = new LinkedHashMap<>();
dataMap.put("multi_name", "雄霸");
dataMap.put("multi_age", "44");
valueOperations.multiSet(dataMap);//同時設置多個key-value
//輸出:[雄霸, 44]
System.out.println(valueOperations.multiGet(Arrays.asList(new String[]{"multi_name", "multi_age"})));
}
}
列表(List)
org.springframework.data.redis.core.ListOperations 處理 List 類型數據:
方法 | 描述 |
---|---|
Long size(K key) | 返回存儲在鍵中的列表的長度。鍵不存在時,返回 0;key 存儲的值不是列表時返回錯誤。 |
Long leftPush(K key, V value | 將指定的值插入到列表的頭部。鍵不存在自動創建。(從左邊插入)。返回 list 的大小(size)。 |
Long leftPushAll(K key, V... values) | 批量從左插入。key 不能爲 null。返回 list 的大小(size)。 |
Long leftPushAll(K key, Collection values) | 批量從左插入。key,values 不能爲 null。 |
Long leftPush(K key, V pivot, V value) | 對於名字爲 key 的 list,從左往右先查詢第一個出現的 pivot 元素,然後將 value 插入到它的左邊。 |
Long leftPushIfPresent(K key, V value) | 只有當 key 存在時,才新增,否則不處理。 |
Long rightPush(K key, V value) | 右側插入,key 不存在時,自動創建 |
Long rightPush(K key, V pivot, V value) | 從左往右查找第一個 pivot 元素,然後將新的 value 插入到它的右側。 |
Long rightPushAll(K key, Collection values) | 右側批量插入 |
Long rightPushAll(K key, V... values) | 右側批量插入 |
Long rightPushIfPresent(K key, V value) | 當 key 存在時,進行右側插入,否則不處理。 |
set(K key, long index, V value) | 爲名字爲 key 的列表索引爲 index 的元素替換爲新的 value 值。key 必須存在,index 索引不能越界 |
Long remove(K key, long count, Object value) | 刪除列表(key) 中指定個數(count)的元素(value)。count=0:刪除所有 value;count>0:從左往右刪除 count 個 value;count<0,從右往左刪除。 |
List range(K key, long start, long end) | 查詢 list 的元素值,索引範圍爲 [start,end],-1 表示倒數第一個元素 |
V index(K key, long index) | 獲取列表中指定索引處的元素。index 越界時,返回 null;key 不存在時,返回 null。索引 index=-1 表示倒數第一個元素。 |
V leftPop(K key) | 彈出最左邊的元素,彈出之後該值在列表中將不復存在。當列表爲空時,返回 null。 |
V rightPop(K key) | 彈出最右邊的元素,彈出之後該值在列表中將不復存在。當列表爲空時,返回 null。 |
V leftPop(K key, long timeout, TimeUnit unit) | 彈出最左邊的元素,當元素不存在時,線程阻塞等待,直到存在新元素,或者超時拋出異常 |
V rightPop(K key, long timeout, TimeUnit unit) | 彈出最右邊的元素,當元素不存在時,線程阻塞等待,直到存在新元素,或者超時拋出異常 |
//org.springframework.data.redis.core.ListOperations 處理 List 類型數據
@Test
public void test2() {
redisTemplate.getConnectionFactory().getConnection().flushAll();//清空 redis 所有緩存的數據。
ListOperations<String, String> opsForList = stringRedisTemplate.opsForList();
Long aLong1 = opsForList.leftPush("list_1", "USA");//將值添加到 list 頭部
Long aLong2 = opsForList.leftPush("list_1", "China");//將值添加到 list 頭部
Long aLong3 = opsForList.leftPushAll("list_1", new String[]{"Java", "C++", "USA", "WPF"});//將多個值添加到 list 頭部
Long size = opsForList.size("list_1");//獲取 list 大小
Long aLong4 = opsForList.leftPush("list_1", "Java", "C#");//將值添加到 list 頭部
Long aLong5 = opsForList.rightPush("list_1", "USA", "Tomcat");//將值添加到 list 頭部
//輸出:1, 2, 6, 7, 8, 6
System.out.println(aLong1 + ", " + aLong2 + ", " + aLong3 + ", " + aLong4 + ", " + aLong5 + ", " + size);
System.out.println(opsForList.range("list_1", 0, -1));//輸出:[WPF, USA, Tomcat, C++, C#, Java, China, USA]
Long aLong = opsForList.leftPushIfPresent("list_2", "Apple");//當 key 存在時,才進行添加
System.out.println(aLong + ", " + aLong5);//0, 8
opsForList.rightPush("list_2", "2019");//將值添加到 list 尾部
opsForList.rightPush("list_2", "2018");
opsForList.rightPush("list_2", "2017");
opsForList.set("list_2", 1, "2008");
System.out.println(opsForList.range("list_2", 0, -1));//獲取指定索引範圍的值,[2019, 2008, 2017]
//同時將多個值添加到右側
opsForList.rightPushAll("list_3", new String[]{"mysql", "oracle", "sql server", "redis", "oracle", "sql server", "redis", "oracle"});
System.out.println(opsForList.range("list_3", 0, -1));//輸出:[mysql, oracle, sql server, redis, oracle, sql server, redis, oracle]
//刪除 list 中所有的 "sql server" 值
Long remove1 = opsForList.remove("list_3", 0, "sql server");//2 - [mysql, oracle, redis, oracle, redis, oracle]
System.out.println(remove1 + " - " + opsForList.range("list_3", 0, -1));
//從右往左刪除第一次出現的 redis 值
Long remove2 = opsForList.remove("list_3", -1, "redis");//1 - [mysql, oracle, redis, oracle, oracle]
System.out.println(remove2 + " - " + opsForList.range("list_3", 0, -1));
//從左往右刪除第一次、第二次出現的 oracle 值
Long remove3 = opsForList.remove("list_3", 2, "oracle");//2 - [mysql, redis, oracle]
System.out.println(remove3 + " - " + opsForList.range("list_3", 0, -1));
opsForList.rightPushAll("list_4", new String[]{"mysql", "oracle", "redis", "DB2"});
String index1 = opsForList.index("list_4", -1);//查詢倒數第一個元素
String leftPop1 = opsForList.leftPop("list_4");//彈出頭部第一個元素
String rightPop1 = opsForList.rightPop("list_4");//彈出尾部第一個元素
System.out.println(index1 + ", " + leftPop1 + ", " + rightPop1);//DB2, mysql, DB2
opsForList.rightPushAll("list_5", new String[]{"Python", "C#", "Java"});
for (int i = 0; i < 4; i++) {
//彈出頭部元素,當超過60秒還沒有元素時,拋出異常 RedisCommandTimeoutException
//System.out.println(opsForList.leftPop("list_5", 60, TimeUnit.SECONDS));//可以手動通過 redis 客戶添加元素:lpush list_5 wmx
}
}
哈希(Hash)
org.springframework.data.redis.core.HashOperations 處理 Hash 類型數據:
方法 | 描述 |
---|---|
Long size(H key) | 獲取指定 hash(key) 的元素個數,kye 不存在時,返回 0 |
Boolean hasKey(H key, Object hashKey) | 判斷 hash 中 是否存在指定的元素,key 不存在時,返回 false |
Set keys(H key) | 獲取指定 hash(key) 中所有的 hashKey。key 不存在時,返回空集合[]. |
List values(H key) | 獲取指定 hash(key) 的所有值。key 不存在時,返回空 list |
Long delete(H key, Object... hashKeys) | 刪除指定的 hash(key) 中指定的元素(hansKeys),返回成功刪除元素個數,key 不存在時返回 0 |
void put(H key, HK hashKey, HV value) | 往 key 中插入鍵值對 hashKey-value。hashKey 重複時,後插入的覆蓋舊值。key 不存在時,自動新增 |
void putAll(H key, Map<? extends HK, ? extends HV> m) | 單次插入多個元素。key 不存在時自動新增 |
Boolean putIfAbsent(H key, HK hashKey, HV value) | key 或者 hashKey 不存在時,才插入值 |
HV get(H key, Object hashKey) | 獲取 hash 中指定的 hashKey,key 不存在時,返回 null. |
Map<HK, HV> entries(H key) | 獲取指定 key 的 hash map。key 不存在時,返回空 map。 |
Long lengthOfValue(H key, HK hashKey) | 獲取 key 對應的 hash map 的 hashKey 對應的元素值的長度 |
List multiGet(H key, Collection hashKeys) | 同時獲取 key 對應的 hash map 中的多個元素值,hashKey 不存在時,返回 null |
Long increment(H key, HK hashKey, long delta) | 爲指定 key 的 hash map 中的元素 hashKey 的數值加上整數值 delta。key 不存在時,直接新增。 |
Double increment(H key, HK hashKey, double delta) | 爲指定 key 的 hash map 中的元素 hashKey 的數值加上浮點數值 delta。key 不存在時,直接新增 |
//org.springframework.data.redis.core.HashOperations 處理 hash 數據類型
@Test
public void test3() {
redisTemplate.getConnectionFactory().getConnection().flushAll();//清空 redis 所有緩存的數據。
HashOperations<String, Object, Object> opsForHash = stringRedisTemplate.opsForHash();
Long delete = opsForHash.delete("hash_1", "name", "age");//刪除指定元素
Boolean hasKey = opsForHash.hasKey("hash_1", "name");//判斷是否含有指定的元素
Object name1 = opsForHash.get("hash_1", "name");//獲取指定的元素
Set<Object> keys = opsForHash.keys("hash_1");//獲取所有的 key
Long hash_1 = opsForHash.size("hash_1");//獲取 hash 的大小
System.out.println(delete + ", " + hasKey + ", " + name1 + ", " + keys + ", " + hash_1);//輸出:0, false, null, [], 0
Map<String, String> dataMap = new HashMap<>();
dataMap.put("age", "33");
dataMap.put("name", "Li Si");
dataMap.put("address", "人民東路45號");
opsForHash.put("hash_1", "name", "Zan San");//爲 hash 添加單個元素
opsForHash.putAll("hash_1", dataMap);//爲 hash 添加多個元素
opsForHash.putIfAbsent("hash_2", "name", "Chang Sha");//當 key 或者 hashKey 不存在時,才插入值
List<Object> list = opsForHash.values("hash_1");//獲取所有的 values
Map<Object, Object> entries = opsForHash.entries("hash_1");//獲取整個 hash
Long lengthOfValue1 = opsForHash.lengthOfValue("hash_1", "name");//獲取元素的長度
Long lengthOfValue2 = opsForHash.lengthOfValue("hash_1", "age");
List<Object> multiGet = opsForHash.multiGet("hash_1", Arrays.asList(new String[]{"name", "address", "birthday"}));//同時獲取多個元素值
//[Li Si, 人民東路45號, 33], {name=Li Si, address=人民東路45號, age=33}, 5, 2, [Li Si, 人民東路45號, null]
System.out.println(list + ", " + entries + ", " + lengthOfValue1 + ", " + lengthOfValue2 + ", " + multiGet);
Long increment_age1 = opsForHash.increment("hash_1", "age", 20);//數值元素做加法
Double increment_age2 = opsForHash.increment("hash_1", "age", 20.45D);
System.out.println(increment_age1 + ", " + increment_age2);//53, 73.45
}
集合(Set)
org.springframework.data.redis.core.SetOperations 處理無序集合(Set) 類型數據:
方法 | 描述 |
---|---|
Long add(K key, V... values) | 往 set 中添加元素,key 不存在時,自動新建。value 重複時,覆蓋舊值。返回 set 中的元素個數 |
Long remove(K key, Object... values) | 移除 set 中的元素。返回 set 中剩餘的元素個數. |
Boolean move(K key, V value, K destKey) | 將 key 對應的 set 中的值 value 剪切到目標 set(destKey) 中。key、value、destKey 不存在時,不做任何操作. |
V pop(K key) | 隨機彈出 set 中的一個元素,彈出後,set 中就沒有了。當 set 爲空時,返回 null. |
List pop(K key, long count) | 隨機彈出 set 中 count 個元素,如果 set 的大小爲 3,而 count 爲 5,此時只會返回 3 個元素。 |
Long size(K key) | 獲取 key 對應 set 的集合大小. key 不存在時,返回 0 |
Set members(K key) | 獲取 set 中所有的元素,key 不存在時,返回空 set. |
V randomMember(K key) | 從 set 中隨機返回一個元素,set 中此元素還會存在。key 不存在時,返回 null. |
List randomMembers(K key, long count) | 隨機返回 set 中 count 個元素。 |
Boolean isMember(K key, Object o) | 判斷 key 對應的 set 中是否包含元素 o。key 不存在時,返回 false。 |
Set union(K key, K otherKey) | 獲取 key 與 otherKey 對應的 set 的並集。舊值不受影響,返回合併後的值。 |
Set union(K key, Collection otherKeys) | 獲取多個 set 的並集 |
Long unionAndStore(K key, K otherKey, K destKey) | 求 key 、otherKey 的 set 並集,並將結果添加到 destKey 中。destKey 不存在時,自動創建。返回新集合中的元素個數。當 destKey 中事先已經有值,則會被先清除。 |
Long unionAndStore(K key, Collection otherKeys, K destKey) | 將多個 set 的並集結果放入到 destKey 對應的 set 中,destKey 不存在時,自動創建。當 destKey 中事先已經有值,則會被先清除。 |
Set difference(K key, K otherKey) | 求 key 與 otherKey 對應的 set 的差集,key 減去 otherKey 後剩餘的結果。 |
Set difference(K key, Collection otherKeys) | 獲取 key 與所有 otherKeys 的差集。 |
Long differenceAndStore(K key, K otherKey, K destKey) | 將差集結果放入到 destKey 中。當 destKey 中事先已經有值,則會被先清除。 |
Long differenceAndStore(K key, Collection otherKeys, K destKey) | 將差集結果放入到 destKey 中。當 destKey 中事先已經有值,則會被先清除。 |
Set intersect(K key, K otherKey) | 獲取 key 與 otherKey 的交集,雙方都擁有的元素 |
Set intersect(K key, Collection otherKeys) | 獲取 key 與其它所有 otherKeys 的交集 |
Long intersectAndStore(K key, K otherKey, K destKey) | 將交集結果放到 destKey 集合中。當 destKey 中事先已經有值,則會被先清除。 |
Long intersectAndStore(K key, Collection otherKeys, K destKey) | 將交集結果放到 destKey 集合中。當 destKey 中事先已經有值,則會被先清除。 |
//org.springframework.data.redis.core.SetOperations 處理 Set 類型數據:
@Test
public void test4() {
stringRedisTemplate.getConnectionFactory().getConnection().flushAll();//情況所有緩存數據
SetOperations<String, String> opsForSet = stringRedisTemplate.opsForSet();
Long add = opsForSet.add("set_1", "C", "Java", "Python");//往集合添加元素
Long remove = opsForSet.remove("set_1", "C");//刪除元素
String set_1 = opsForSet.pop("set_1");//隨機彈出 set 中的一個元素
System.out.println(add + ", " + remove + ", " + set_1);//3, 1, Python
opsForSet.add("set_2", "華山", "泰山", "衡山");
Set<String> set_2 = opsForSet.members("set_2");//查詢 set 中的所有元素
opsForSet.move("set_1", "Java", "set_2");
System.out.println(set_2);//[泰山, 衡山, 華山]
Long size = opsForSet.size("set_2");//獲取 set 的大小
System.out.println(opsForSet.members("set_2") + ", " + size);//[泰山, 衡山, 華山], 3
Boolean member1 = opsForSet.isMember("set_2", "泰山");//判斷 set 中是否含義指定的元素值
Boolean member2 = opsForSet.isMember("set_2", "嵩山");
System.out.println(member1 + ", " + member2);//true, false
opsForSet.add("set_3", "Oracle", "Mysql", "DB2", "H2", "Sql Server");
List<String> set_3 = opsForSet.pop("set_3", 3);
System.out.println(set_3);//[Oracle, DB2, Mysql]
opsForSet.add("set_4", "段譽", "喬峯", "虛竹", "王語嫣", "慕容復");
System.out.println(opsForSet.members("set_4") + ", " + opsForSet.randomMember("set_41"));
System.out.println(opsForSet.randomMembers("set_4", 3));//隨機彈出 set 中指定個數的元素,如隨機彈出其中3個元素
opsForSet.add("set_5_1", "a", "b", "c", "1", "2", "3");
opsForSet.add("set_5_2", "x", "y", "c", "21", "2", "3");
Set<String> union1 = opsForSet.union("set_5_1", "set_5_2");//兩個集合求並集
System.out.println(opsForSet.members("set_5_1") + ", " + opsForSet.members("set_5_2"));
System.out.println(union1);//[3, a, x, c, b, 2, 21, 1, y]
//多個集合求並集
Set<String> set_5_1 = opsForSet.union("set_5_1", Arrays.asList(new String[]{"set_5_2", "set_4"}));
System.out.println(set_5_1);//[王語嫣, 段譽, 21, a, 3, 虛竹, x, b, c, 慕容復, 1, y, 喬峯, 2]
//多個集合求並集,並將結果存儲到新的集合中
Long aLong = opsForSet.unionAndStore("set_5_1", "set_5_2", "set_5_3");
System.out.println(aLong + ", " + opsForSet.members("set_5_3"));//9, [3, a, x, c, b, 2, 21, 1, y]
Set<String> difference = opsForSet.difference("set_5_1", "set_5_2");//求兩個集合的差集
System.out.println(difference);//[a, 1, b]
Set<String> intersect = opsForSet.intersect("set_5_1", "set_5_2");//求兩個集合的交集
opsForSet.intersectAndStore("set_5_1", "set_5_2", "set_5_3");//當set_5_3集合中有值時,會先被清除
System.out.println(intersect);//[3, c, 2]
}
有序集合(sorted set)
org.springframework.data.redis.core.ZSetOperations 處理有序集合(Set) 的數據:
方法 | 描述 |
---|---|
Boolean add(K key, V value, double score) | 爲有序集合添加元素. 如果 value 已經存在,則更新. score 表示權重,用於排序,值越小,排序越靠前(由小到大)。key 不存在時,直接新增。成功插入時返回 true,失敗時返回 false。 |
Long rank(K key, Object o) | 獲取元素 o 在有序集合中的索引 |
Set range(K key, long start, long end) | 獲取有序的集合中指定索引範圍的值,索引從0開始,-1 表示倒數第一個元素。 |
Set rangeByScore(K key, double min, double max) | 根據權重範圍查詢 |
Set rangeByScore(K key, double min, double max, long offset, long count) | offset 表示偏移量,count 表示需要獲取的個數 |
Long count(K key, double min, double max) | 獲取權重在 [min,max] 直接的元素個數 |
Long remove(K key, Object... values) | 刪除有序集合中指定的元素(value) |
Long removeRange(K key, long start, long end) | 刪除有序集合中指定索引範圍內的元素 |
Long removeRangeByScore(K key, double min, double max) | 刪除有序集合中指定權重範圍內的元素 |
Long zCard(K key) | 獲取集合的大小 |
Long size(K key) | 獲取集合的大小,底層調用 zCard |
Double score(K key, Object o) | 獲取集合中指定元素的權重。 |
//org.springframework.data.redis.core.ZSetOperations 處理有序集合(Set) 的數據:
@Test
public void test5() {
stringRedisTemplate.getConnectionFactory().getConnection().flushAll();//清空所有緩存
ZSetOperations<String, String> opsForZSet = stringRedisTemplate.opsForZSet();
Boolean add1 = opsForZSet.add("zset1", "C++", 3.8);
Boolean add2 = opsForZSet.add("zset1", "Java", 0.3);
Boolean add3 = opsForZSet.add("zset1", "Python", 2.5);
Set<String> zset1 = opsForZSet.range("zset1", 0, -1);
System.out.println(add1 + ", " + add2 + ", " + add3 + ", " + zset1);//輸出:true, true, true, [Java, Python, C++]
Long rank = opsForZSet.rank("zset1", "C++");
Long count = opsForZSet.count("zset1", 0.3, 2.5);
Long size = opsForZSet.size("zset1");
Double score = opsForZSet.score("zset1", "Java");
//輸出:2, 2, 3, 0.3, [Java, Python, C++]
System.out.println(rank + ", " + count + ", " + size + ", " + score + ", " +
opsForZSet.range("zset1", 0, -1));
opsForZSet.add("zset2", "12", 0);
opsForZSet.add("zset2", "3c", 1);
opsForZSet.add("zset2", "4f", 2);
opsForZSet.add("zset2", "6h", 3);
opsForZSet.add("zset2", "7p", 4);
Long remove = opsForZSet.remove("zset2", "4f");
//Long aLong = opsForZSet.removeRange("zset2", 1, 2);
Long zset2 = opsForZSet.removeRangeByScore("zset2", 2.0, 3.0);
System.out.println(opsForZSet.range("zset2", 0, -1));
}