Springboot2.2.9整合Redis(lettuce、RedisCacheManager、RedisLockRegistry)
阿新 • • 發佈:2020-08-10
一、先記錄下一些遇到的問題:
1、使用springboot 2.1.16版本時,編譯警告:lettuce-core:jar:5.1.8.RELEASE is invalid
解決方法:
升級springboot版本。2.1.16版本預設引用了lettuce-core:jar:5.1.8.RELEASE版本,但是從警告可知,該版本已不可用。升級springboot到2.2.9版本,編譯通過,檢視引用lettuce-core版本為5.2.2,問題解決。
2、啟動報錯:NoClassDefFoundError: org/apache/commons/pool2/impl/GenericObjectPoolConfig
解決方法:
網上查詢原因為:在springboot2.x以後官方預設使用了Redis的lettuce客戶端來代替jedis客戶端,替換的原因是Lettuce的底層是基於Netty實現的,效能更加出色。ettuce在底層的執行緒池管理中依賴了commons-pool2,如果不引入這個包就會直接報錯,所以引入:commons-pool2
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> <version>2.8.0</version> </dependency>
3、執行時報錯:cannot deserialize from Object value (no delegate- or property-based Creator)
解決方法:
主要是序列化問題,在異常中找到錯誤的bean,加上無參構造器即可!
二、依賴如下:
<dependencies> <!-- springboot redis快取引入 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <!-- 分散式鎖引入 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-integration</artifactId> </dependency> <dependency> <groupId>org.springframework.integration</groupId> <artifactId>spring-integration-redis</artifactId> </dependency> <!-- lettuce pool 快取連線池 --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> <version>2.8.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- jackson引入 --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.11.0</version> </dependency> </dependencies>
三、springboot2.x的redis配置資訊application.properties:
#######################################################
# 配置檔案redis伺服器器配置 #
#######################################################
# Redis資料庫索引(預設為0)
spring.redis.database=0
# Redis叢集
spring.redis.cluster.nodes=xxx.xxx.xxx.91:6379,xxx.xxx.xxx.92:6379
# Redis伺服器地址
spring.redis.host=xxx.xxx.xxx.91
# Redis伺服器連線埠
spring.redis.port=6379
# Redis伺服器連線密碼(預設為空)
spring.redis.password=
# 連線池最大連線數(使用負值表示沒有限制)
spring.redis.lettuce.pool.max-active=8
# 連線池最大阻塞等待時間(使用負值表示沒有限制)
spring.redis.lettuce.pool.max-wait=-1ms
# 連線池中的最大空閒連線
spring.redis.lettuce.pool.max-idle=8
# 連線池中的最小空閒連線
spring.redis.lettuce.pool.min-idle=0
# 連線超時時間(毫秒)
spring.redis.timeout=60000ms
# redis快取過期時間
#Redis過期時間型別:year/day/hour/minute/second\n" +
EXPIRED_TYPE=day
EXPIRED_TIME=3
四、RedisTemplate配置,redis相關bean配置:
import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.beans.factory.annotation.Value; import org.springframework.cache.annotation.CachingConfigurerSupport; import org.springframework.cache.annotation.EnableCaching; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.data.redis.cache.RedisCacheConfiguration; import org.springframework.data.redis.cache.RedisCacheManager; import org.springframework.data.redis.cache.RedisCacheWriter; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.*; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; import org.springframework.integration.redis.util.RedisLockRegistry; import java.time.Duration; /** * <redis配置> * * @author zxx * @since 1.0.0 */ @Configuration @EnableCaching public class RedisConfig extends CachingConfigurerSupport { // 從配置檔案獲取redis過期型別 @Value("${EXPIRED_TYPE}") private String EXPIRED_TYPE; // 從配置檔案獲取redis過期時間 @Value("${EXPIRED_TIME}") private int EXPIRED_TIME; /** * 選擇redis作為預設快取工具 */ @Bean @Primary public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) { // 設定過期引數 Duration ttl; switch (EXPIRED_TYPE) { case "year": ttl = Duration.ofDays(365 * EXPIRED_TIME); break; case "day": ttl = Duration.ofDays(EXPIRED_TIME); break; case "hour": ttl = Duration.ofHours(EXPIRED_TIME); break; case "minute": ttl = Duration.ofMinutes(EXPIRED_TIME); break; case "second": ttl = Duration.ofSeconds(EXPIRED_TIME); break; default: ttl = Duration.ofDays(3); break; } // 設定快取有效期 RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig() .entryTtl(ttl); return RedisCacheManager.builder(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory)) .cacheDefaults(redisCacheConfiguration).build(); } /** * redis分散式鎖設計 */ @Bean public RedisLockRegistry redisLockRegistry(RedisConnectionFactory redisConnectionFactory) { return new RedisLockRegistry(redisConnectionFactory, "Poseidon:similarity"); } /** * redisTemplate自定義配置 */ @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); // 配置連線工廠 template.setConnectionFactory(factory); ObjectMapper om = new ObjectMapper(); // 指定要序列化的域,field,get和set,以及修飾符範圍,ANY是都有包括private和public om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); // 指定序列化輸入的型別,類必須是非final修飾的,final修飾的類,比如String,Integer等會丟擲異常 // om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); // enableDefaultTyping方法廢棄,新方法適配 om.activateDefaultTyping(om.getPolymorphicTypeValidator(), ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.WRAPPER_ARRAY); // 使用Jackson2JsonRedisSerializer來序列化和反序列化redis的value值(預設使用JDK的序列化方式) Jackson2JsonRedisSerializer<Object> jacksonSerial = new Jackson2JsonRedisSerializer<>(Object.class); jacksonSerial.setObjectMapper(om); // 使用StringRedisSerializer來序列化和反序列化redis的key值 template.setKeySerializer(new StringRedisSerializer()); // 值採用json序列化 template.setValueSerializer(jacksonSerial); // 設定hash key 和value序列化模式 template.setHashKeySerializer(new StringRedisSerializer()); template.setHashValueSerializer(jacksonSerial); template.afterPropertiesSet(); return template; } /** * 對redis字串型別資料操作 */ @Bean public ValueOperations<String, Object> valueOperations(RedisTemplate<String, Object> redisTemplate) { return redisTemplate.opsForValue(); } /** * 對hash型別的資料操作 */ @Bean public HashOperations<String, String, Object> hashOperations(RedisTemplate<String, Object> redisTemplate) { return redisTemplate.opsForHash(); } /** * 對連結串列型別的資料操作 */ @Bean public ListOperations<String, Object> listOperations(RedisTemplate<String, Object> redisTemplate) { return redisTemplate.opsForList(); } /** * 對無序集合型別的資料操作 */ @Bean public SetOperations<String, Object> setOperations(RedisTemplate<String, Object> redisTemplate) { return redisTemplate.opsForSet(); } /** * 對有序集合型別的資料操作 */ @Bean public ZSetOperations<String, Object> zSetOperations(RedisTemplate<String, Object> redisTemplate) { return redisTemplate.opsForZSet(); } }
說明:
- spring-redis中使用了RedisTemplate來進行redis的操作,通過泛型的K和V設定鍵值對的物件型別。這裡使用了string作為key的物件型別,值為Object。
- 對spring-redis對redis的五種資料型別也有支援
- HashOperations:對hash型別的資料操作
- ValueOperations:對redis字串型別資料操作
- ListOperations:對連結串列型別的資料操作
- SetOperations:對無序集合型別的資料操作
- ZSetOperations:對有序集合型別的資料操作
五、Redis操作工具類:
package com.abc5w.poseidon.similarityprocessor.utils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.connection.DataType; import org.springframework.data.redis.core.Cursor; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.ScanOptions; import org.springframework.data.redis.core.ZSetOperations; import org.springframework.stereotype.Component; import java.util.*; import java.util.concurrent.TimeUnit; /** * <Redis工具> * * @time 2020-07-24 16:00 * @since 1.0.0 */ @Component public class RedisUtil { private static Logger logger = LoggerFactory.getLogger(RedisUtil.class); @Autowired private RedisTemplate<String, Object> redisTemplate; /** -------------------key相關操作--------------------- */ /** * 刪除key * * @param key */ public void delete(String key) { redisTemplate.delete(key); } /** * 批量刪除key * * @param keys */ public void delete(Collection<String> keys) { redisTemplate.delete(keys); } /** * 序列化key * * @param key * @return */ public byte[] dump(String key) { return redisTemplate.dump(key); } /** * 是否存在key * * @param key * @return */ public Boolean hasKey(String key) { return redisTemplate.hasKey(key); } /** * 設定過期時間 * * @param key * @param timeout * @param unit * @return */ public Boolean expire(String key, long timeout, TimeUnit unit) { return redisTemplate.expire(key, timeout, unit); } /** * 設定過期時間 * * @param key * @param date * @return */ public Boolean expireAt(String key, Date date) { return redisTemplate.expireAt(key, date); } /** * 查詢匹配的key * * @param pattern * @return */ public Set<String> keys(String pattern) { return redisTemplate.keys(pattern); } /** * 將當前資料庫的 key 移動到給定的資料庫 db 當中 * * @param key * @param dbIndex * @return */ public Boolean move(String key, int dbIndex) { return redisTemplate.move(key, dbIndex); } /** * 移除 key 的過期時間,key 將持久保持 * * @param key * @return */ public Boolean persist(String key) { return redisTemplate.persist(key); } /** * 返回 key 的剩餘的過期時間 * * @param key * @param unit * @return */ public Long getExpire(String key, TimeUnit unit) { return redisTemplate.getExpire(key, unit); } /** * 返回 key 的剩餘的過期時間 * * @param key * @return */ public Long getExpire(String key) { return redisTemplate.getExpire(key); } /** * 從當前資料庫中隨機返回一個 key * * @return */ public String randomKey() { return redisTemplate.randomKey(); } /** * 修改 key 的名稱 * * @param oldKey * @param newKey */ public void rename(String oldKey, String newKey) { redisTemplate.rename(oldKey, newKey); } /** * 僅當 newkey 不存在時,將 oldKey 改名為 newkey * * @param oldKey * @param newKey * @return */ public Boolean renameIfAbsent(String oldKey, String newKey) { return redisTemplate.renameIfAbsent(oldKey, newKey); } /** * 返回 key 所儲存的值的型別 * * @param key * @return */ public DataType type(String key) { return redisTemplate.type(key); } /** -------------------string相關操作--------------------- */ /** * 設定指定 key 的值 * * @param key * @param value */ public void set(String key, Object value) { redisTemplate.opsForValue().set(key, value); } /** * 獲取指定 key 的值 * * @param key * @return */ public Object get(String key) { return redisTemplate.opsForValue().get(key); } /** * 返回 key 中字串值的子字元 * * @param key * @param start * @param end * @return */ public String getRange(String key, long start, long end) { return redisTemplate.opsForValue().get(key, start, end); } /** * 將給定 key 的值設為 value ,並返回 key 的舊值(old value) * * @param key * @param value * @return */ public Object getAndSet(String key, Object value) { return redisTemplate.opsForValue().getAndSet(key, value); } /** * 對 key 所儲存的字串值,獲取指定偏移量上的位(bit) * * @param key * @param offset * @return */ public Boolean getBit(String key, long offset) { return redisTemplate.opsForValue().getBit(key, offset); } /** * 批量獲取 * * @param keys * @return */ public List<Object> multiGet(Collection<String> keys) { return redisTemplate.opsForValue().multiGet(keys); } /** * 設定ASCII碼, 字串'a'的ASCII碼是97, 轉為二進位制是'01100001', 此方法是將二進位制第offset位值變為value * * @param key 位置 * @param value 值,true為1, false為0 * @return */ public boolean setBit(String key, long offset, boolean value) { return redisTemplate.opsForValue().setBit(key, offset, value); } /** * 將值 value 關聯到 key ,並將 key 的過期時間設為 timeout * * @param key * @param value * @param timeout 過期時間 * @param unit 時間單位, 天:TimeUnit.DAYS 小時:TimeUnit.HOURS 分鐘:TimeUnit.MINUTES * 秒:TimeUnit.SECONDS 毫秒:TimeUnit.MILLISECONDS */ public void setEx(String key, Object value, long timeout, TimeUnit unit) { redisTemplate.opsForValue().set(key, value, timeout, unit); } /** * 只有在 key 不存在時設定 key 的值 * * @param key * @param value * @return 之前已經存在返回false, 不存在返回true */ public boolean setIfAbsent(String key, String value) { return redisTemplate.opsForValue().setIfAbsent(key, value); } /** * 用 value 引數覆寫給定 key 所儲存的字串值,從偏移量 offset 開始 * * @param key * @param value * @param offset 從指定位置開始覆寫 */ public void setRange(String key, String value, long offset) { redisTemplate.opsForValue().set(key, value, offset); } /** * 獲取字串的長度 * * @param key * @return */ public Long size(String key) { return redisTemplate.opsForValue().size(key); } /** * 批量新增 * * @param maps */ public void multiSet(Map<String, String> maps) { redisTemplate.opsForValue().multiSet(maps); } /** * 同時設定一個或多個 key-value 對,當且僅當所有給定 key 都不存在 * * @param maps * @return 之前已經存在返回false, 不存在返回true */ public boolean multiSetIfAbsent(Map<String, String> maps) { return redisTemplate.opsForValue().multiSetIfAbsent(maps); } /** * 增加(自增長), 負數則為自減 * * @param key * @return */ public Long incrBy(String key, long increment) { return redisTemplate.opsForValue().increment(key, increment); } /** * @param key * @return */ public Double incrByFloat(String key, double increment) { return redisTemplate.opsForValue().increment(key, increment); } /** * 追加到末尾 * * @param key * @param value * @return */ public Integer append(String key, String value) { return redisTemplate.opsForValue().append(key, value); } /** -------------------hash相關操作------------------------- */ /** * 獲取儲存在雜湊表中指定欄位的值 * * @param key * @param field * @return */ public Object hGet(String key, String field) { return redisTemplate.opsForHash().get(key, field); } /** * 獲取所有給定欄位的值 * * @param key * @return */ public Map<Object, Object> hGetAll(String key) { return redisTemplate.opsForHash().entries(key); } /** * 獲取所有給定欄位的值 * * @param key * @param fields * @return */ public List<Object> hMultiGet(String key, Collection<Object> fields) { return redisTemplate.opsForHash().multiGet(key, fields); } public void hPut(String key, String hashKey, String value) { redisTemplate.opsForHash().put(key, hashKey, value); } public void hPutAll(String key, Map<String, String> maps) { redisTemplate.opsForHash().putAll(key, maps); } /** * 僅當hashKey不存在時才設定 * * @param key * @param hashKey * @param value * @return */ public Boolean hPutIfAbsent(String key, String hashKey, String value) { return redisTemplate.opsForHash().putIfAbsent(key, hashKey, value); } /** * 刪除一個或多個雜湊表字段 * * @param key * @param fields * @return */ public Long hDelete(String key, Object... fields) { return redisTemplate.opsForHash().delete(key, fields); } /** * 檢視雜湊表 key 中,指定的欄位是否存在 * * @param key * @param field * @return */ public boolean hExists(String key, String field) { return redisTemplate.opsForHash().hasKey(key, field); } /** * 為雜湊表 key 中的指定欄位的整數值加上增量 increment * * @param key * @param field * @param increment * @return */ public Long hIncrBy(String key, Object field, long increment) { return redisTemplate.opsForHash().increment(key, field, increment); } /** * 為雜湊表 key 中的指定欄位的整數值加上增量 increment * * @param key * @param field * @param delta * @return */ public Double hIncrByFloat(String key, Object field, double delta) { return redisTemplate.opsForHash().increment(key, field, delta); } /** * 獲取所有雜湊表中的欄位 * * @param key * @return */ public Set<Object> hKeys(String key) { return redisTemplate.opsForHash().keys(key); } /** * 獲取雜湊表中欄位的數量 * * @param key * @return */ public Long hSize(String key) { return redisTemplate.opsForHash().size(key); } /** * 獲取雜湊表中所有值 * * @param key * @return */ public List<Object> hValues(String key) { return redisTemplate.opsForHash().values(key); } /** * 迭代雜湊表中的鍵值對 * * @param key * @param options * @return */ public Cursor<Map.Entry<Object, Object>> hScan(String key, ScanOptions options) { return redisTemplate.opsForHash().scan(key, options); } /** ------------------------list相關操作---------------------------- */ /** * 通過索引獲取列表中的元素 * * @param key * @param index * @return */ public Object lIndex(String key, long index) { return redisTemplate.opsForList().index(key, index); } /** * 獲取列表指定範圍內的元素 * * @param key * @param start 開始位置, 0是開始位置 * @param end 結束位置, -1返回所有 * @return */ public List<Object> lRange(String key, long start, long end) { return redisTemplate.opsForList().range(key, start, end); } /** * 儲存在list頭部 * * @param key * @param value * @return */ public Long lLeftPush(String key, String value) { return redisTemplate.opsForList().leftPush(key, value); } /** * @param key * @param value * @return */ public Long lLeftPushAll(String key, String... value) { return redisTemplate.opsForList().leftPushAll(key, value); } /** * @param key * @param value * @return */ public Long lLeftPushAll(String key, Collection<String> value) { return redisTemplate.opsForList().leftPushAll(key, value); } /** * 當list存在的時候才加入 * * @param key * @param value * @return */ public Long lLeftPushIfPresent(String key, String value) { return redisTemplate.opsForList().leftPushIfPresent(key, value); } /** * 如果pivot存在,再pivot前面新增 * * @param key * @param pivot * @param value * @return */ public Long lLeftPush(String key, String pivot, String value) { return redisTemplate.opsForList().leftPush(key, pivot, value); } /** * @param key * @param value * @return */ public Long lRightPush(String key, String value) { return redisTemplate.opsForList().rightPush(key, value); } /** * @param key * @param value * @return */ public Long lRightPushAll(String key, String... value) { return redisTemplate.opsForList().rightPushAll(key, value); } /** * @param key * @param value * @return */ public Long lRightPushAll(String key, Collection<String> value) { return redisTemplate.opsForList().rightPushAll(key, value); } /** * 為已存在的列表新增值 * * @param key * @param value * @return */ public Long lRightPushIfPresent(String key, String value) { return redisTemplate.opsForList().rightPushIfPresent(key, value); } /** * 在pivot元素的右邊新增值 * * @param key * @param pivot * @param value * @return */ public Long lRightPush(String key, String pivot, String value) { return redisTemplate.opsForList().rightPush(key, pivot, value); } /** * 通過索引設定列表元素的值 * * @param key * @param index 位置 * @param value */ public void lSet(String key, long index, String value) { redisTemplate.opsForList().set(key, index, value); } /** * 移出並獲取列表的第一個元素 * * @param key * @return 刪除的元素 */ public Object lLeftPop(String key) { return redisTemplate.opsForList().leftPop(key); } /** * 移出並獲取列表的第一個元素, 如果列表沒有元素會阻塞列表直到等待超時或發現可彈出元素為止 * * @param key * @param timeout 等待時間 * @param unit 時間單位 * @return */ public Object lBLeftPop(String key, long timeout, TimeUnit unit) { return redisTemplate.opsForList().leftPop(key, timeout, unit); } /** * 移除並獲取列表最後一個元素 * * @param key * @return 刪除的元素 */ public Object lRightPop(String key) { return redisTemplate.opsForList().rightPop(key); } /** * 移出並獲取列表的最後一個元素, 如果列表沒有元素會阻塞列表直到等待超時或發現可彈出元素為止 * * @param key * @param timeout 等待時間 * @param unit 時間單位 * @return */ public Object lBRightPop(String key, long timeout, TimeUnit unit) { return redisTemplate.opsForList().rightPop(key, timeout, unit); } /** * 移除列表的最後一個元素,並將該元素新增到另一個列表並返回 * * @param sourceKey * @param destinationKey * @return */ public Object lRightPopAndLeftPush(String sourceKey, String destinationKey) { return redisTemplate.opsForList().rightPopAndLeftPush(sourceKey, destinationKey); } /** * 從列表中彈出一個值,將彈出的元素插入到另外一個列表中並返回它; 如果列表沒有元素會阻塞列表直到等待超時或發現可彈出元素為止 * * @param sourceKey * @param destinationKey * @param timeout * @param unit * @return */ public Object lBRightPopAndLeftPush(String sourceKey, String destinationKey, long timeout, TimeUnit unit) { return redisTemplate.opsForList().rightPopAndLeftPush(sourceKey, destinationKey, timeout, unit); } /** * 刪除集合中值等於value得元素 * * @param key * @param index index=0, 刪除所有值等於value的元素; index>0, 從頭部開始刪除第一個值等於value的元素; * index<0, 從尾部開始刪除第一個值等於value的元素; * @param value * @return */ public Long lRemove(String key, long index, String value) { return redisTemplate.opsForList().remove(key, index, value); } /** * 裁剪list * * @param key * @param start * @param end */ public void lTrim(String key, long start, long end) { redisTemplate.opsForList().trim(key, start, end); } /** * 獲取列表長度 * * @param key * @return */ public Long lLen(String key) { return redisTemplate.opsForList().size(key); } /** --------------------set相關操作-------------------------- */ /** * set新增元素 * * @param key * @param values * @return */ public Long sAdd(String key, String... values) { return redisTemplate.opsForSet().add(key, values); } /** * set移除元素 * * @param key * @param values * @return */ public Long sRemove(String key, Object... values) { return redisTemplate.opsForSet().remove(key, values); } /** * 移除並返回集合的一個隨機元素 * * @param key * @return */ public Object sPop(String key) { return redisTemplate.opsForSet().pop(key); } /** * 將元素value從一個集合移到另一個集合 * * @param key * @param value * @param destKey * @return */ public Boolean sMove(String key, String value, String destKey) { return redisTemplate.opsForSet().move(key, value, destKey); } /** * 獲取集合的大小 * * @param key * @return */ public Long sSize(String key) { return redisTemplate.opsForSet().size(key); } /** * 判斷集合是否包含value * * @param key * @param value * @return */ public Boolean sIsMember(String key, Object value) { return redisTemplate.opsForSet().isMember(key, value); } /** * 獲取兩個集合的交集 * * @param key * @param otherKey * @return */ public Set<Object> sIntersect(String key, String otherKey) { return redisTemplate.opsForSet().intersect(key, otherKey); } /** * 獲取key集合與多個集合的交集 * * @param key * @param otherKeys * @return */ public Set<Object> sIntersect(String key, Collection<String> otherKeys) { return redisTemplate.opsForSet().intersect(key, otherKeys); } /** * key集合與otherKey集合的交集儲存到destKey集合中 * * @param key * @param otherKey * @param destKey * @return */ public Long sIntersectAndStore(String key, String otherKey, String destKey) { return redisTemplate.opsForSet().intersectAndStore(key, otherKey, destKey); } /** * key集合與多個集合的交集儲存到destKey集合中 * * @param key * @param otherKeys * @param destKey * @return */ public Long sIntersectAndStore(String key, Collection<String> otherKeys, String destKey) { return redisTemplate.opsForSet().intersectAndStore(key, otherKeys, destKey); } /** * 獲取兩個集合的並集 * * @param key * @param otherKeys * @return */ public Set<Object> sUnion(String key, String otherKeys) { return redisTemplate.opsForSet().union(key, otherKeys); } /** * 獲取key集合與多個集合的並集 * * @param key * @param otherKeys * @return */ public Set<Object> sUnion(String key, Collection<String> otherKeys) { return redisTemplate.opsForSet().union(key, otherKeys); } /** * key集合與otherKey集合的並集儲存到destKey中 * * @param key * @param otherKey * @param destKey * @return */ public Long sUnionAndStore(String key, String otherKey, String destKey) { return redisTemplate.opsForSet().unionAndStore(key, otherKey, destKey); } /** * key集合與多個集合的並集儲存到destKey中 * * @param key * @param otherKeys * @param destKey * @return */ public Long sUnionAndStore(String key, Collection<String> otherKeys, String destKey) { return redisTemplate.opsForSet().unionAndStore(key, otherKeys, destKey); } /** * 獲取兩個集合的差集 * * @param key * @param otherKey * @return */ public Set<Object> sDifference(String key, String otherKey) { return redisTemplate.opsForSet().difference(key, otherKey); } /** * 獲取key集合與多個集合的差集 * * @param key * @param otherKeys * @return */ public Set<Object> sDifference(String key, Collection<String> otherKeys) { return redisTemplate.opsForSet().difference(key, otherKeys); } /** * key集合與otherKey集合的差集儲存到destKey中 * * @param key * @param otherKey * @param destKey * @return */ public Long sDifference(String key, String otherKey, String destKey) { return redisTemplate.opsForSet().differenceAndStore(key, otherKey, destKey); } /** * key集合與多個集合的差集儲存到destKey中 * * @param key * @param otherKeys * @param destKey * @return */ public Long sDifference(String key, Collection<String> otherKeys, String destKey) { return redisTemplate.opsForSet().differenceAndStore(key, otherKeys, destKey); } /** * 獲取集合所有元素 * * @param key * @return */ public Set<Object> sMembers(String key) { return redisTemplate.opsForSet().members(key); } /** * 隨機獲取集合中的一個元素 * * @param key * @return */ public Object sRandomMember(String key) { return redisTemplate.opsForSet().randomMember(key); } /** * 隨機獲取集合中count個元素 * * @param key * @param count * @return */ public List<Object> sRandomMembers(String key, long count) { return redisTemplate.opsForSet().randomMembers(key, count); } /** * 隨機獲取集合中count個元素並且去除重複的 * * @param key * @param count * @return */ public Set<Object> sDistinctRandomMembers(String key, long count) { return redisTemplate.opsForSet().distinctRandomMembers(key, count); } /** * @param key * @param options * @return */ public Cursor<Object> sScan(String key, ScanOptions options) { return redisTemplate.opsForSet().scan(key, options); } /**------------------zSet相關操作--------------------------------*/ /** * 新增元素,有序集合是按照元素的score值由小到大排列 * * @param key * @param value * @param score * @return */ public Boolean zAdd(String key, String value, double score) { return redisTemplate.opsForZSet().add(key, value, score); } /** * @param key * @param values * @return */ public Long zAdd(String key, Set<ZSetOperations.TypedTuple<Object>> values) { return redisTemplate.opsForZSet().add(key, values); } /** * @param key * @param values * @return */ public Long zRemove(String key, Object... values) { return redisTemplate.opsForZSet().remove(key, values); } /** * 增加元素的score值,並返回增加後的值 * * @param key * @param value * @param delta * @return */ public Double zIncrementScore(String key, String value, double delta) { return redisTemplate.opsForZSet().incrementScore(key, value, delta); } /** * 返回元素在集合的排名,有序集合是按照元素的score值由小到大排列 * * @param key * @param value * @return 0表示第一位 */ public Long zRank(String key, Object value) { return redisTemplate.opsForZSet().rank(key, value); } /** * 返回元素在集合的排名,按元素的score值由大到小排列 * * @param key * @param value * @return */ public Long zReverseRank(String key, Object value) { return redisTemplate.opsForZSet().reverseRank(key, value); } /** * 獲取集合的元素, 從小到大排序 * * @param key * @param start 開始位置 * @param end 結束位置, -1查詢所有 * @return */ public Set<Object> zRange(String key, long start, long end) { return redisTemplate.opsForZSet().range(key, start, end); } /** * 獲取集合元素, 並且把score值也獲取 * * @param key * @param start * @param end * @return */ public Set<ZSetOperations.TypedTuple<Object>> zRangeWithScores(String key, long start, long end) { return redisTemplate.opsForZSet().rangeWithScores(key, start, end); } /** * 根據Score值查詢集合元素 * * @param key * @param min 最小值 * @param max 最大值 * @return */ public Set<Object> zRangeByScore(String key, double min, double max) { return redisTemplate.opsForZSet().rangeByScore(key, min, max); } /** * 根據Score值查詢集合元素, 從小到大排序 * * @param key * @param min 最小值 * @param max 最大值 * @return */ public Set<ZSetOperations.TypedTuple<Object>> zRangeByScoreWithScores(String key, double min, double max) { return redisTemplate.opsForZSet().rangeByScoreWithScores(key, min, max); } /** * @param key * @param min * @param max * @param start * @param end * @return */ public Set<ZSetOperations.TypedTuple<Object>> zRangeByScoreWithScores(String key, double min, double max, long start, long end) { return redisTemplate.opsForZSet().rangeByScoreWithScores(key, min, max, start, end); } /** * 獲取集合的元素, 從大到小排序 * * @param key * @param start * @param end * @return */ public Set<Object> zReverseRange(String key, long start, long end) { return redisTemplate.opsForZSet().reverseRange(key, start, end); } /** * 獲取集合的元素, 從大到小排序, 並返回score值 * * @param key * @param start * @param end * @return */ public Set<ZSetOperations.TypedTuple<Object>> zReverseRangeWithScores(String key, long start, long end) { return redisTemplate.opsForZSet().reverseRangeWithScores(key, start, end); } /** * 根據Score值查詢集合元素, 從大到小排序 * * @param key * @param min * @param max * @return */ public Set<Object> zReverseRangeByScore(String key, double min, double max) { return redisTemplate.opsForZSet().reverseRangeByScore(key, min, max); } /** * 根據Score值查詢集合元素, 從大到小排序 * * @param key * @param min * @param max * @return */ public Set<ZSetOperations.TypedTuple<Object>> zReverseRangeByScoreWithScores( String key, double min, double max) { return redisTemplate.opsForZSet().reverseRangeByScoreWithScores(key, min, max); } /** * @param key * @param min * @param max * @param start * @param end * @return */ public Set<Object> zReverseRangeByScore(String key, double min, double max, long start, long end) { return redisTemplate.opsForZSet().reverseRangeByScore(key, min, max, start, end); } /** * 根據score值獲取集合元素數量 * * @param key * @param min * @param max * @return */ public Long zCount(String key, double min, double max) { return redisTemplate.opsForZSet().count(key, min, max); } /** * 獲取集合大小 * * @param key * @return */ public Long zSize(String key) { return redisTemplate.opsForZSet().size(key); } /** * 獲取集合大小 * * @param key * @return */ public Long zZCard(String key) { return redisTemplate.opsForZSet().zCard(key); } /** * 獲取集合中value元素的score值 * * @param key * @param value * @return */ public Double zScore(String key, Object value) { return redisTemplate.opsForZSet().score(key, value); } /** * 移除指定索引位置的成員 * * @param key * @param start * @param end * @return */ public Long zRemoveRange(String key, long start, long end) { return redisTemplate.opsForZSet().removeRange(key, start, end); } /** * 根據指定的score值的範圍來移除成員 * * @param key * @param min * @param max * @return */ public Long zRemoveRangeByScore(String key, double min, double max) { return redisTemplate.opsForZSet().removeRangeByScore(key, min, max); } /** * 獲取key和otherKey的並集並存儲在destKey中 * * @param key * @param otherKey * @param destKey * @return */ public Long zUnionAndStore(String key, String otherKey, String destKey) { return redisTemplate.opsForZSet().unionAndStore(key, otherKey, destKey); } /** * @param key * @param otherKeys * @param destKey * @return */ public Long zUnionAndStore(String key, Collection<String> otherKeys, String destKey) { return redisTemplate.opsForZSet() .unionAndStore(key, otherKeys, destKey); } /** * 交集 * * @param key * @param otherKey * @param destKey * @return */ public Long zIntersectAndStore(String key, String otherKey, String destKey) { return redisTemplate.opsForZSet().intersectAndStore(key, otherKey, destKey); } /** * 交集 * * @param key * @param otherKeys * @param destKey * @return */ public Long zIntersectAndStore(String key, Collection<String> otherKeys, String destKey) { return redisTemplate.opsForZSet().intersectAndStore(key, otherKeys, destKey); } /** * @param key * @param options * @return */ public Cursor<ZSetOperations.TypedTuple<Object>> zScan(String key, ScanOptions options) { return redisTemplate.opsForZSet().scan(key, options); } }
六、Redis Key生成工具類:
package com.abc5w.poseidon.similarityprocessor.utils; /** * <redis鍵的生成工具類> * * @author zxx * @since 1.0.0 */ public class RedisKeyUtil { /** * redis的key,具體檢視README.md * 形式為: * 表名(固定):一級索引(固定):二級索引(自定義,結尾對應在redis儲存形式):鍵 -> 值 * * @param index2 索引2 * @param key 鍵 * @return */ public static String getKey(String index2, String key) { return "例如專案名:例如子專案名:" + index2 + ":" + key; } }
說明:
- 將key按照特定格式生成,有助於後期維護及相關key操作
- 儘量在儲存之前設計好資料的儲存格式,做好記錄及註釋,方便後續人員理解與操作
六、具體使用方法:
只放上幾個小例子,其它類似
//---------------------- set操作 ---------------------- // 封裝獲取所有hash2BasketIdKeySet的redis鍵格式 String hash2BasketIdKeySetRedisKey = RedisKeyUtil.getKey("hash2BasketIdKeySet", "allKeys"); Set<Object> hash2BasketIdKeySetRedisValue = redisUtil.sMembers(hash2BasketIdKeySetRedisKey); //---------------------- String操作(序列化set) ---------------------- String docHashRedisKey = RedisKeyUtil.getKey("hash2BasketIdSet", docHash); Set<String> hash2BasketIdSet = new HashSet<>(); hash2BasketIdSet.add(newBasketId); redisUtil.setEx(docHashRedisKey, hash2BasketIdSet, 3, TimeUnit.DAYS); String title2BasketIdSetRedisKey = RedisKeyUtil.getKey("title2BasketIdSet", docTitle); Set<String> title2BasketIdSetRedisValue = (Set<String>) redisUtil.get(title2BasketIdSetRedisKey);