From 3c07a4aa0a1a07dde0761b97e31e854ea14b5dee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A6=82=E6=A2=A6=E6=8A=80=E6=9C=AF?= <596392912@qq.com> Date: Wed, 3 Nov 2021 11:12:44 +0800 Subject: [PATCH] =?UTF-8?q?:sparkles:=20=E4=BC=98=E5=8C=96=20mica-redis?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mica/redis/cache/MicaRedisCache.java | 163 ++++++++++++++---- 1 file changed, 128 insertions(+), 35 deletions(-) diff --git a/mica-redis/src/main/java/net/dreamlu/mica/redis/cache/MicaRedisCache.java b/mica-redis/src/main/java/net/dreamlu/mica/redis/cache/MicaRedisCache.java index 42b60e62..d69f7fdf 100644 --- a/mica-redis/src/main/java/net/dreamlu/mica/redis/cache/MicaRedisCache.java +++ b/mica-redis/src/main/java/net/dreamlu/mica/redis/cache/MicaRedisCache.java @@ -18,10 +18,12 @@ package net.dreamlu.mica.redis.cache; import lombok.Getter; import net.dreamlu.mica.core.utils.CollectionUtil; +import net.dreamlu.mica.core.utils.JsonUtil; import org.springframework.data.redis.core.*; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.lang.Nullable; +import java.nio.charset.StandardCharsets; import java.time.Duration; import java.util.*; import java.util.concurrent.TimeUnit; @@ -113,6 +115,30 @@ public class MicaRedisCache { return (T) valueOps.get(key); } + /** + * 返回 key 所关联的 value 值,采用 jdk 序列化 + * 如果 key 不存在那么返回特殊值 nil 。 + */ + @Nullable + public T getByJdkSer(String key) { + return (T) redisTemplate.execute((RedisCallback) redis -> { + byte[] bytes = redis.get(keySerialize(key)); + return RedisSerializer.java().deserialize(bytes); + }); + } + + /** + * 返回 key 所关联的 value 值,采用 json 序列化 + * 如果 key 不存在那么返回特殊值 nil 。 + */ + @Nullable + public T getByJsonSer(String key, Class clazz) { + return redisTemplate.execute((RedisCallback) redis -> { + byte[] valueBytes = redis.get(keySerialize(key)); + return JsonUtil.readValue(valueBytes, clazz); + }); + } + /** * 获取cache 为 null 时使用加载器,然后设置缓存 * @@ -135,6 +161,29 @@ public class MicaRedisCache { return value; } + /** + * 获取cache 为 null 时使用加载器,然后设置缓存 + * + * @param key cacheKey + * @param clazz Class + * @param loader cache loader + * @param 泛型 + * @return 结果 + */ + @Nullable + public T getByJsonSer(String key, Class clazz, Supplier loader) { + T value = this.getByJsonSer(key, clazz); + if (value != null) { + return value; + } + value = loader.get(); + if (value == null) { + return null; + } + this.set(key, value); + return value; + } + /** * 返回 key 所关联的 value 值 * 如果 key 不存在那么返回特殊值 nil 。 @@ -144,6 +193,15 @@ public class MicaRedisCache { return (T) valueOps.get(cacheKey.getKey()); } + /** + * 返回 key 所关联的 value 值 + * 如果 key 不存在那么返回特殊值 nil 。 + */ + @Nullable + public T getByJsonSer(CacheKey cacheKey, Class clazz) { + return getByJsonSer(cacheKey.getKey(), clazz); + } + /** * 获取cache 为 null 时使用加载器,然后设置缓存 * @@ -167,6 +225,29 @@ public class MicaRedisCache { return value; } + /** + * 获取cache 为 null 时使用加载器,然后设置缓存 + * + * @param cacheKey cacheKey + * @param loader cache loader + * @param 泛型 + * @return 结果 + */ + @Nullable + public T getByJsonSer(CacheKey cacheKey, Class clazz, Supplier loader) { + String key = cacheKey.getKey(); + T value = this.getByJsonSer(key, clazz); + if (value != null) { + return value; + } + value = loader.get(); + if (value == null) { + return null; + } + this.set(cacheKey, value); + return value; + } + /** * 删除给定的一个 key * 不存在的 key 会被忽略。 @@ -189,6 +270,7 @@ public class MicaRedisCache { * 删除给定的多个 key * 不存在的 key 会被忽略。 */ + @Nullable public Long del(String... keys) { return del(Arrays.asList(keys)); } @@ -243,7 +325,6 @@ public class MicaRedisCache { * * @param pattern 匹配表达式 * @param consumer 消费者 - * @return 扫描结果 */ public void scan(String pattern, Consumer consumer) { scan(pattern, 100L, consumer); @@ -255,11 +336,9 @@ public class MicaRedisCache { * @param pattern 匹配表达式 * @param count 一次扫描的数量 * @param consumer 消费者 - * @return 扫描结果 */ public void scan(String pattern, @Nullable Long count, Consumer consumer) { - RedisSerializer keySerializer = (RedisSerializer) redisTemplate.getKeySerializer(); - scanBytes(pattern, count, (bytes) -> consumer.accept(keySerializer.deserialize(bytes))); + scanBytes(pattern, count, (bytes) -> consumer.accept(keyDeserialize(bytes))); } /** @@ -268,16 +347,15 @@ public class MicaRedisCache { * @param pattern 匹配表达式 * @param count 一次扫描的数量 * @param consumer 消费者 - * @return 扫描结果 */ public void scanBytes(String pattern, @Nullable Long count, Consumer consumer) { - redisTemplate.execute((RedisCallback) action -> { + redisTemplate.execute((RedisCallback) redis -> { ScanOptions.ScanOptionsBuilder builder = ScanOptions.scanOptions() .match(pattern); if (count != null) { builder.count(count); } - try (Cursor cursor = action.scan(builder.build())) { + try (Cursor cursor = redis.scan(builder.build())) { cursor.forEachRemaining(consumer); } return null; @@ -331,8 +409,7 @@ public class MicaRedisCache { * @return 扫描结果 */ public void sScan(String key, String pattern, @Nullable Long count, Consumer consumer) { - RedisSerializer keySerializer = (RedisSerializer) redisTemplate.getKeySerializer(); - sScanBytes(key, pattern, count, (bytes) -> consumer.accept(keySerializer.deserialize(bytes))); + sScanBytes(key, pattern, count, (bytes) -> consumer.accept(keyDeserialize(bytes))); } /** @@ -345,14 +422,13 @@ public class MicaRedisCache { * @return 扫描结果 */ public void sScanBytes(String key, String pattern, @Nullable Long count, Consumer consumer) { - RedisSerializer keySerializer = (RedisSerializer) redisTemplate.getKeySerializer(); - redisTemplate.execute((RedisCallback) action -> { + redisTemplate.execute((RedisCallback) redis -> { ScanOptions.ScanOptionsBuilder builder = ScanOptions.scanOptions() .match(pattern); if (count != null) { builder.count(count); } - try (Cursor cursor = action.sScan(keySerializer.serialize(key), builder.build())) { + try (Cursor cursor = redis.sScan(keySerialize(key), builder.build())) { cursor.forEachRemaining(consumer); } return null; @@ -424,11 +500,10 @@ public class MicaRedisCache { * 关于更多递增(increment) / 递减(decrement)操作的更多信息,请参见 INCR 命令。 */ public Long decrBy(String key, long longValue, long seconds) { - RedisSerializer keySerializer = (RedisSerializer) redisTemplate.getKeySerializer(); - byte[] serializedKey = keySerializer.serialize(key); - List result = redisTemplate.executePipelined((RedisCallback) action -> { - Long data = action.decrBy(serializedKey, longValue); - action.expire(serializedKey, seconds); + byte[] serializedKey = keySerialize(key); + List result = redisTemplate.executePipelined((RedisCallback) redis -> { + Long data = redis.decrBy(serializedKey, longValue); + redis.expire(serializedKey, seconds); return data; }); return (Long) result.get(0); @@ -465,11 +540,10 @@ public class MicaRedisCache { * 关于递增(increment) / 递减(decrement)操作的更多信息,参见 INCR 命令。 */ public Long incrBy(String key, long longValue, long seconds) { - RedisSerializer keySerializer = (RedisSerializer) redisTemplate.getKeySerializer(); - byte[] serializedKey = keySerializer.serialize(key); - List result = redisTemplate.executePipelined((RedisCallback) action -> { - Long data = action.incrBy(serializedKey, longValue); - action.expire(serializedKey, seconds); + byte[] serializedKey = keySerialize(key); + List result = redisTemplate.executePipelined((RedisCallback) redis -> { + Long data = redis.incrBy(serializedKey, longValue); + redis.expire(serializedKey, seconds); return data; }); return (Long) result.get(0); @@ -482,10 +556,12 @@ public class MicaRedisCache { */ @Nullable public Long getCounter(String key) { - RedisSerializer keySerializer = (RedisSerializer) redisTemplate.getKeySerializer(); - return redisTemplate.execute((RedisCallback) action -> { - byte[] value = action.get(keySerializer.serialize(key)); - return Long.valueOf(new String(value)); + return redisTemplate.execute((RedisCallback) redis -> { + byte[] value = redis.get(keySerialize(key)); + if (value == null) { + return null; + } + return Long.valueOf(new String(value, StandardCharsets.UTF_8)); }); } @@ -498,17 +574,16 @@ public class MicaRedisCache { */ @Nullable public Long getCounter(String key, long seconds, Supplier loader) { - RedisSerializer keySerializer = (RedisSerializer) redisTemplate.getKeySerializer(); - return redisTemplate.execute((RedisCallback) action -> { - byte[] keyBytes = keySerializer.serialize(key); - byte[] value = action.get(keyBytes); + return redisTemplate.execute((RedisCallback) redis -> { + byte[] keyBytes = keySerialize(key); + byte[] value = redis.get(keyBytes); long longValue; if (value != null) { - longValue = Long.valueOf(new String(value)); + longValue = Long.parseLong(new String(value, StandardCharsets.UTF_8)); } else { Long loaderValue = loader.get(); longValue = loaderValue == null ? 0 : loaderValue; - action.setEx(keyBytes, seconds, String.valueOf(longValue).getBytes()); + redis.setEx(keyBytes, seconds, String.valueOf(longValue).getBytes()); } return longValue; }); @@ -1059,9 +1134,7 @@ public class MicaRedisCache { @Nullable public Long zAdd(String key, Map scoreMembers) { Set> tuples = new HashSet<>(); - scoreMembers.forEach((k, v) -> { - tuples.add(new DefaultTypedTuple<>(k, v)); - }); + scoreMembers.forEach((k, v) -> tuples.add(new DefaultTypedTuple<>(k, v))); return zSetOps.add(key, tuples); } @@ -1159,4 +1232,24 @@ public class MicaRedisCache { return zSetOps.score(key, member); } + /** + * redisKey 序列化 + * + * @param redisKey redisKey + * @return byte array + */ + public static byte[] keySerialize(String redisKey) { + return Objects.requireNonNull(RedisSerializer.string().serialize(redisKey), "Redis key is null."); + } + + /** + * redisKey 序列化 + * + * @param redisKey redisKey + * @return byte array + */ + public static String keyDeserialize(byte[] redisKey) { + return Objects.requireNonNull(RedisSerializer.string().deserialize(redisKey), "Redis key is null."); + } + } -- GitLab