From 5a4b4721268a8d5af866c8dd37e83f60a2f53226 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E6=9D=8E?= <1040978436@qq.com> Date: Thu, 8 Jan 2026 16:16:29 +0800 Subject: [PATCH] =?UTF-8?q?update=20redis=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/common-redis/pom.xml | 62 +++ .../common/redis/config/RedisConfig.java | 49 +++ .../tacit/common/redis/utils/RedisUtils.java | 404 ++++++++++++++++++ .../main/resources/META-INF/spring.factories | 2 + 4 files changed, 517 insertions(+) create mode 100644 common/common-redis/pom.xml create mode 100644 common/common-redis/src/main/java/com/tacit/common/redis/config/RedisConfig.java create mode 100644 common/common-redis/src/main/java/com/tacit/common/redis/utils/RedisUtils.java create mode 100644 common/common-redis/src/main/resources/META-INF/spring.factories diff --git a/common/common-redis/pom.xml b/common/common-redis/pom.xml new file mode 100644 index 0000000..cd90fa7 --- /dev/null +++ b/common/common-redis/pom.xml @@ -0,0 +1,62 @@ + + + + common + com.tacit + 1.0.0-SNAPSHOT + ../pom.xml + + 4.0.0 + + common-redis + Common Redis + Redis service module for common usage + + + + + org.springframework.boot + spring-boot-starter-data-redis + + + + + redis.clients + jedis + + + + + com.tacit + common-model + ${project.version} + + + + + com.fasterxml.jackson.core + jackson-databind + + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.11.0 + + ${java.version} + ${java.version} + UTF-8 + + + + + diff --git a/common/common-redis/src/main/java/com/tacit/common/redis/config/RedisConfig.java b/common/common-redis/src/main/java/com/tacit/common/redis/config/RedisConfig.java new file mode 100644 index 0000000..23fc2d9 --- /dev/null +++ b/common/common-redis/src/main/java/com/tacit/common/redis/config/RedisConfig.java @@ -0,0 +1,49 @@ +package com.tacit.common.redis.config; + +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.PropertyAccessor; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; +import org.springframework.data.redis.serializer.StringRedisSerializer; + +@Configuration +public class RedisConfig { + + @Bean + public RedisTemplate redisTemplate(RedisConnectionFactory factory) { + RedisTemplate template = new RedisTemplate<>(); + template.setConnectionFactory(factory); + + // key 使用 String 序列化 + template.setKeySerializer(new StringRedisSerializer()); + template.setHashKeySerializer(new StringRedisSerializer()); + + // value 使用 JSON 序列化 + Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer<>(Object.class); + ObjectMapper mapper = new ObjectMapper(); + + // 设置字段可见性 + mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); + + // 支持 JSR310 日期时间类型 + mapper.registerModule(new JavaTimeModule()); + + // 新版 Jackson 安全的多态类型配置 + mapper.activateDefaultTyping( + LaissezFaireSubTypeValidator.instance, + ObjectMapper.DefaultTyping.NON_FINAL + ); + + template.setValueSerializer(serializer); + template.setHashValueSerializer(serializer); + + template.afterPropertiesSet(); + return template; + } +} \ No newline at end of file diff --git a/common/common-redis/src/main/java/com/tacit/common/redis/utils/RedisUtils.java b/common/common-redis/src/main/java/com/tacit/common/redis/utils/RedisUtils.java new file mode 100644 index 0000000..3346b52 --- /dev/null +++ b/common/common-redis/src/main/java/com/tacit/common/redis/utils/RedisUtils.java @@ -0,0 +1,404 @@ +package com.tacit.common.redis.utils; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.stereotype.Component; + +import java.util.*; +import java.util.concurrent.TimeUnit; + +/** + * @Description: Redis工具类,提供全面的Redis操作方法 + * @Author: lidongjin + * @CreateTime: 2026-01-07 09:27 + */ +@Slf4j +@Component +public class RedisUtils { + @Autowired(required = false) + private RedisTemplate redisTemplate; + + @Autowired(required = false) + private StringRedisTemplate stringRedisTemplate; + + // ============================ String ============================= + + /** + * 普通字符串设置 + * @param key 键 + * @param value 值 + */ + public void set(String key, String value) { + stringRedisTemplate.opsForValue().set(key, value); + } + + /** + * 普通字符串设置并指定过期时间 + * @param key 键 + * @param value 值 + * @param time 时间 + * @param timeUnit 时间单位 + */ + public void set(String key, String value, long time, TimeUnit timeUnit) { + stringRedisTemplate.opsForValue().set(key, value, time, timeUnit); + } + + /** + * 普通字符串设置并指定过期时间(秒) + * @param key 键 + * @param value 值 + * @param seconds 过期时间(秒) + */ + public void set(String key, String value, int seconds) { + stringRedisTemplate.opsForValue().set(key, value, seconds, TimeUnit.SECONDS); + } + + /** + * 获取普通字符串 + * @param key 键 + * @return 值 + */ + public String get(String key) { + return stringRedisTemplate.opsForValue().get(key); + } + + // ============================ Object ============================= + + /** + * 对象设置 + * @param key 键 + * @param value 值 + */ + public void setObject(String key, Object value) { + redisTemplate.opsForValue().set(key, value); + } + + /** + * 对象设置并指定过期时间 + * @param key 键 + * @param value 值 + * @param time 时间 + * @param timeUnit 时间单位 + */ + public void setObject(String key, Object value, long time, TimeUnit timeUnit) { + redisTemplate.opsForValue().set(key, value, time, timeUnit); + } + + /** + * 对象设置并指定过期时间(秒) + * @param key 键 + * @param value 值 + * @param seconds 过期时间(秒) + */ + public void setObject(String key, Object value, int seconds) { + redisTemplate.opsForValue().set(key, value, seconds, TimeUnit.SECONDS); + } + + /** + * 获取对象 + * @param key 键 + * @param 对象类型 + * @return 对象 + */ + @SuppressWarnings("unchecked") + public T getObject(String key) { + return (T) redisTemplate.opsForValue().get(key); + } + + // ============================ Hash ============================= + + /** + * Hash设置 + * @param key 键 + * @param hashKey hash键 + * @param value 值 + */ + public void hset(String key, String hashKey, Object value) { + redisTemplate.opsForHash().put(key, hashKey, value); + } + + /** + * Hash获取 + * @param key 键 + * @param hashKey hash键 + * @param 对象类型 + * @return 值 + */ + @SuppressWarnings("unchecked") + public T hget(String key, String hashKey) { + return (T) redisTemplate.opsForHash().get(key, hashKey); + } + + /** + * Hash获取所有字段 + * @param key 键 + * @return 所有键值对 + */ + public Map hgetAll(String key) { + return redisTemplate.opsForHash().entries(key); + } + + /** + * Hash批量设置 + * @param key 键 + * @param map hash键值对 + */ + public void hmset(String key, Map map) { + redisTemplate.opsForHash().putAll(key, map); + } + + /** + * Hash删除 + * @param key 键 + * @param hashKeys hash键(可以多个) + */ + public void hdel(String key, Object... hashKeys) { + redisTemplate.opsForHash().delete(key, hashKeys); + } + + /** + * Hash判断字段是否存在 + * @param key 键 + * @param hashKey hash键 + * @return 是否存在 + */ + public boolean hExists(String key, String hashKey) { + return redisTemplate.opsForHash().hasKey(key, hashKey); + } + + // ============================ List ============================= + + /** + * List左 push + * @param key 键 + * @param value 值 + */ + public void lpush(String key, Object value) { + redisTemplate.opsForList().leftPush(key, value); + } + + /** + * List右 push + * @param key 键 + * @param value 值 + */ + public void rpush(String key, Object value) { + redisTemplate.opsForList().rightPush(key, value); + } + + /** + * List左 pop + * @param key 键 + * @param 对象类型 + * @return 值 + */ + @SuppressWarnings("unchecked") + public T lpop(String key) { + return (T) redisTemplate.opsForList().leftPop(key); + } + + /** + * List右 pop + * @param key 键 + * @param 对象类型 + * @return 值 + */ + @SuppressWarnings("unchecked") + public T rpop(String key) { + return (T) redisTemplate.opsForList().rightPop(key); + } + + /** + * List获取指定范围的值 + * @param key 键 + * @param start 开始位置 + * @param end 结束位置 + * @param 对象类型 + * @return 值列表 + */ + @SuppressWarnings("unchecked") + public List lrange(String key, long start, long end) { + return (List) redisTemplate.opsForList().range(key, start, end); + } + + /** + * List获取长度 + * @param key 键 + * @return 长度 + */ + public long llen(String key) { + return redisTemplate.opsForList().size(key); + } + + // ============================ Set ============================= + + /** + * Set添加元素 + * @param key 键 + * @param values 值(可以多个) + */ + public void sadd(String key, Object... values) { + redisTemplate.opsForSet().add(key, values); + } + + /** + * Set获取所有元素 + * @param key 键 + * @param 对象类型 + * @return 元素集合 + */ + @SuppressWarnings("unchecked") + public Set smembers(String key) { + return (Set) redisTemplate.opsForSet().members(key); + } + + /** + * Set判断元素是否存在 + * @param key 键 + * @param value 值 + * @return 是否存在 + */ + public boolean sismember(String key, Object value) { + return redisTemplate.opsForSet().isMember(key, value); + } + + /** + * Set删除元素 + * @param key 键 + * @param values 值(可以多个) + */ + public void srem(String key, Object... values) { + redisTemplate.opsForSet().remove(key, values); + } + + /** + * Set获取大小 + * @param key 键 + * @return 大小 + */ + public long scard(String key) { + return redisTemplate.opsForSet().size(key); + } + + // ============================ Sorted Set ============================= + + /** + * Sorted Set添加元素 + * @param key 键 + * @param value 值 + * @param score 分数 + */ + public void zadd(String key, Object value, double score) { + redisTemplate.opsForZSet().add(key, value, score); + } + + /** + * Sorted Set获取指定范围的元素(升序) + * @param key 键 + * @param start 开始位置 + * @param end 结束位置 + * @param 对象类型 + * @return 元素集合 + */ + @SuppressWarnings("unchecked") + public Set zrange(String key, long start, long end) { + return (Set) redisTemplate.opsForZSet().range(key, start, end); + } + + /** + * Sorted Set获取指定分数范围的元素 + * @param key 键 + * @param min 最小分数 + * @param max 最大分数 + * @param 对象类型 + * @return 元素集合 + */ + @SuppressWarnings("unchecked") + public Set zrangeByScore(String key, double min, double max) { + return (Set) redisTemplate.opsForZSet().rangeByScore(key, min, max); + } + + /** + * Sorted Set删除元素 + * @param key 键 + * @param values 值(可以多个) + */ + public void zrem(String key, Object... values) { + redisTemplate.opsForZSet().remove(key, values); + } + + /** + * Sorted Set获取大小 + * @param key 键 + * @return 大小 + */ + public long zcard(String key) { + return redisTemplate.opsForZSet().size(key); + } + + // ============================ Key ============================= + + /** + * 删除键 + * @param key 键(可以多个) + */ + public void delete(String... keys) { + if (keys != null && keys.length > 0) { + if (keys.length == 1) { + redisTemplate.delete(keys[0]); + } else { + redisTemplate.delete(Arrays.asList(keys)); + } + } + } + + /** + * 判断键是否存在 + * @param key 键 + * @return 是否存在 + */ + public boolean hasKey(String key) { + return redisTemplate.hasKey(key); + } + + /** + * 设置键过期时间 + * @param key 键 + * @param time 时间 + * @param timeUnit 时间单位 + * @return 是否设置成功 + */ + public boolean expire(String key, long time, TimeUnit timeUnit) { + return Boolean.TRUE.equals(redisTemplate.expire(key, time, timeUnit)); + } + + /** + * 设置键过期时间(秒) + * @param key 键 + * @param seconds 过期时间(秒) + * @return 是否设置成功 + */ + public boolean expire(String key, int seconds) { + return Boolean.TRUE.equals(redisTemplate.expire(key, seconds, TimeUnit.SECONDS)); + } + + /** + * 获取键过期时间 + * @param key 键 + * @return 过期时间(秒),-1表示永久有效 + */ + public long getExpire(String key) { + return redisTemplate.getExpire(key, TimeUnit.SECONDS); + } + + /** + * 查找匹配的键 + * @param pattern 匹配模式,如:user:* + * @return 匹配的键列表 + */ + public Set keys(String pattern) { + return redisTemplate.keys(pattern); + } +} diff --git a/common/common-redis/src/main/resources/META-INF/spring.factories b/common/common-redis/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000..47fa066 --- /dev/null +++ b/common/common-redis/src/main/resources/META-INF/spring.factories @@ -0,0 +1,2 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +com.tacit.common.redis.config.RedisConfig \ No newline at end of file