1.环境搭建
1.创建模块
2.查看是否交给父模块管理
3.引入依靠
- <?xml version="1.0" encoding="UTF-8"?>
- <project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>com.sunxiansheng</groupId>
- <artifactId>sunrays-common</artifactId>
- <version>1.0</version>
- </parent>
- <version>1.0</version>
- <artifactId>common-redis-starter</artifactId>
- <dependencies>
- <!-- redis -->
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-data-redis</artifactId>
- <!-- 排除,防止日志冲突 -->
- <exclusions>
- <exclusion>
- <artifactId>spring-boot-starter-logging</artifactId>
- <groupId>org.springframework.boot</groupId>
- </exclusion>
- </exclusions>
- </dependency>
- <!-- 集成 redis 所需 commons-pool2 -->
- <dependency>
- <groupId>org.apache.commons</groupId>
- <artifactId>commons-pool2</artifactId>
- </dependency>
- </dependencies>
- </project>
复制代码 4.自动配置
1.目次
2.RedisAutoConfiguration.java
- package com.sunxiansheng.redis.config;
- import org.springframework.context.annotation.Configuration;
- /**
- * Description: Redis自动配置类
- *
- * @Author sun
- * @Create 2024/11/15 20:41
- * @Version 1.0
- */
- @Configuration
- public class RedisAutoConfiguration {
- }
复制代码 3.spring.factories
- org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
- com.sunxiansheng.redis.config.RedisAutoConfiguration
复制代码 2.重写RedisTemplate
1.引入Jackson
- <!-- 重写RedisTemplate所需要的Jackson -->
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-databind</artifactId>
- </dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-annotations</artifactId>
- </dependency>
复制代码 2.编写RedisConfig.java

- package com.sunxiansheng.redis.config;
- import com.fasterxml.jackson.annotation.JsonAutoDetect;
- import com.fasterxml.jackson.annotation.JsonInclude;
- import com.fasterxml.jackson.annotation.PropertyAccessor;
- import com.fasterxml.jackson.databind.DeserializationFeature;
- import com.fasterxml.jackson.databind.ObjectMapper;
- import com.fasterxml.jackson.databind.jsontype.BasicPolymorphicTypeValidator;
- 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.RedisSerializer;
- import org.springframework.data.redis.serializer.StringRedisSerializer;
- /**
- * Redis配置类,会将 Object 类型序列化为 JSON 格式,然后将其作为字符串存储在 Redis 中。
- * 当从 Redis 中读取时,会将 JSON 字符串反序列化回具体的 Object 类型数据,直接强制转换即可,无需手动解析 JSON。
- */
- @Configuration
- public class RedisConfig {
- /**
- * 自定义RedisTemplate Bean,配置Key和Value的序列化方式。
- * Key采用String序列化,Value采用JSON序列化,支持对象直接转为JSON格式存储在Redis中。
- *
- * @param redisConnectionFactory Redis连接工厂,用于创建RedisTemplate连接
- * @return 配置完成的RedisTemplate实例,用于Redis数据操作
- */
- @Bean
- public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
- RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
- redisTemplate.setConnectionFactory(redisConnectionFactory);
- // 设置Key的序列化方式为StringRedisSerializer,以便Key以字符串格式存储,便于人类读取
- RedisSerializer<String> stringSerializer = new StringRedisSerializer();
- redisTemplate.setKeySerializer(stringSerializer); // 序列化Redis键
- redisTemplate.setHashKeySerializer(stringSerializer); // 序列化Hash结构的键
- // 设置Value和HashValue的序列化方式为Jackson2JsonRedisSerializer,以便Value以JSON格式存储
- Jackson2JsonRedisSerializer<Object> jacksonSerializer = jackson2JsonRedisSerializer();
- redisTemplate.setValueSerializer(jacksonSerializer); // 序列化Redis值
- redisTemplate.setHashValueSerializer(jacksonSerializer); // 序列化Hash结构的值
- // 初始化设置的配置
- redisTemplate.afterPropertiesSet();
- return redisTemplate;
- }
- /**
- * 配置Jackson序列化器,以支持复杂Java对象的序列化和反序列化。
- * 使用Jackson2JsonRedisSerializer将对象序列化为JSON字符串,从而提高Redis中的可读性和兼容性。
- *
- * @return 配置好的Jackson2JsonRedisSerializer实例,指定序列化格式为JSON
- */
- private Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer() {
- // 创建Jackson2JsonRedisSerializer,指定泛型为Object,支持序列化任意Java对象
- Jackson2JsonRedisSerializer<Object> jacksonSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
- // 创建ObjectMapper用于配置JSON序列化方式
- ObjectMapper objectMapper = new ObjectMapper();
- // 设置可见性,允许访问所有字段(包括私有和保护字段),确保所有属性都被序列化和反序列化
- objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
- // 配置反序列化时忽略未知属性,防止因JSON中多余字段导致反序列化错误
- objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
- // 序列化时忽略空值属性,节省存储空间
- objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
- // 启用类型信息,确保反序列化时能够恢复原始对象类型
- objectMapper.activateDefaultTyping(
- BasicPolymorphicTypeValidator.builder()
- .allowIfSubType(Object.class)
- .build(),
- ObjectMapper.DefaultTyping.NON_FINAL
- );
- // 将配置好的ObjectMapper设置到Jackson2JsonRedisSerializer中,应用上述配置
- jacksonSerializer.setObjectMapper(objectMapper);
- return jacksonSerializer;
- }
- }
复制代码 3.RedisAutoConfiguration.java 导入配置类
3.Redis工具类
1.RBase.java Redis基础工具类
- package com.sunxiansheng.redis.utils;
- import org.springframework.data.redis.core.RedisTemplate;
- import java.util.Collection;
- import java.util.concurrent.TimeUnit;
- /**
- * Redis基础工具类,提供一些基础的操作
- *
- * @Author sun
- * @Create 2024/11/14 14:25
- * @Version 1.0
- */
- public class RBase {
- protected RedisTemplate<String, Object> redisTemplate;
- public RBase(RedisTemplate<String, Object> redisTemplate) {
- this.redisTemplate = redisTemplate;
- }
- /**
- * 默认的key分隔符
- */
- private static final String DEFAULT_KEY_SEPARATOR = ":";
- /**
- * 构建缓存key(使用默认的key分隔符)
- *
- * @param parts 多个字符串拼接成缓存key
- * @return 拼接后的缓存key
- */
- public String buildKeyByDefaultSeparator(String... parts) {
- return String.join(DEFAULT_KEY_SEPARATOR, parts);
- }
- /**
- * 构建缓存key(使用自定义的key分隔符)
- *
- * @param separator 自定义的key分隔符
- * @param parts 多个字符串拼接成缓存key
- * @return 拼接后的缓存key
- */
- public String buildKeyByCustomSeparator(String separator, String... parts) {
- return String.join(separator, parts);
- }
- /**
- * 删除单个key
- *
- * @param key 键
- * @return 如果键不存在,返回false;如果删除成功,返回true
- */
- public Boolean delete(String key) {
- if (key == null || key.isEmpty()) {
- throw new IllegalArgumentException("Key cannot be null or empty");
- }
- return redisTemplate.delete(key);
- }
- /**
- * 批量删除key
- *
- * @param keys 键的集合
- * @return 成功删除的键的数量,键不存在不计数
- */
- public Long deleteBatch(Collection<String> keys) {
- if (keys == null || keys.isEmpty()) {
- return 0L;
- }
- return redisTemplate.delete(keys);
- }
- /**
- * 指定缓存失效时间
- *
- * @param key 键
- * @param timeout 失效时间(小于等于0 表示 永久有效)
- * @param unit 时间单位
- * @return 设置成功返回true,失败返回false
- */
- public Boolean expire(String key, long timeout, TimeUnit unit) {
- if (key == null || key.isEmpty()) {
- throw new IllegalArgumentException("Key cannot be null or empty");
- }
- if (timeout <= 0) {
- // 或直接返回 true,表示设置为永久有效
- return false;
- }
- return redisTemplate.expire(key, timeout, unit);
- }
- /**
- * 指定缓存失效时间(时间单位:秒)
- *
- * @param key 键
- * @param timeout 失效时间(单位:秒,小于等于0 表示 永久有效)
- * @return 设置成功返回true,失败返回false
- */
- public Boolean expire(String key, long timeout) {
- return expire(key, timeout, TimeUnit.SECONDS);
- }
- /**
- * 获取缓存失效时间
- *
- * @param key 键
- * @return 缓存失效时间(秒)。键不存在返回-2,键存在但没有设置过期时间返回-1
- */
- public Long getExpire(String key) {
- if (key == null || key.isEmpty()) {
- throw new IllegalArgumentException("Key cannot be null or empty");
- }
- return redisTemplate.getExpire(key);
- }
- /**
- * 判断key是否存在
- *
- * @param key 键
- * @return 存在返回true,不存在返回false
- */
- public Boolean hasKey(String key) {
- if (key == null || key.isEmpty()) {
- throw new IllegalArgumentException("Key cannot be null or empty");
- }
- return redisTemplate.hasKey(key);
- }
- /**
- * 转换缓存中的对象为指定类型
- *
- * @param value 缓存中的对象
- * @param type 要转换的目标类型
- * @param <T> 返回的泛型类型
- * @return 转换后的对象
- * @throws ClassCastException 如果对象不能转换为指定类型
- */
- protected <T> T convertValue(Object value, Class<T> type) {
- if (value == null) {
- return null;
- }
- // Long类型的特殊处理,因为Redis中的数据会自动反序列化为Integer
- if (type == Long.class && value instanceof Integer) {
- return type.cast(((Integer) value).longValue());
- }
- if (type.isInstance(value)) {
- return type.cast(value);
- } else {
- throw new ClassCastException("Redis中的对象运行类型与请求转换的类型不匹配,请优先检查Redis配置类是否保存了对象原始信息!期待类型:"
- + type.getName() + ",实际类型:"
- + value.getClass().getName());
- }
- }
- }
复制代码 2.RString.java
- package com.sunxiansheng.redis.utils;
- import org.springframework.data.redis.core.RedisTemplate;
- import java.util.concurrent.TimeUnit;
- /**
- * Description: Redis的String类型操作
- *
- * @Author sun
- * @Create 2024/11/14 14:50
- * @Version 1.1
- */
- public class RString extends RBase {
- /**
- * 构造器给父类注入RedisTemplate
- *
- * @param redisTemplate RedisTemplate实例
- */
- public RString(RedisTemplate<String, Object> redisTemplate) {
- super(redisTemplate);
- }
- /**
- * 设置缓存值
- *
- * @param key 键
- * @param value 值
- */
- public void set(String key, Object value) {
- validateKeyAndValue(key, value);
- redisTemplate.opsForValue().set(key, value);
- }
- /**
- * 设置缓存值并设置过期时间
- *
- * @param key 键
- * @param value 值
- * @param timeout 过期时间
- * @param unit 时间单位
- */
- public void setWithExpire(String key, Object value, final long timeout, final TimeUnit unit) {
- validateKeyAndValue(key, value);
- validateTimeoutAndUnit(timeout, unit);
- redisTemplate.opsForValue().set(key, value, timeout, unit);
- }
- /**
- * 设置缓存值并设置过期时间(单位:秒)
- *
- * @param key 键
- * @param value 值
- * @param timeout 过期时间
- */
- public void setWithExpire(String key, Object value, final long timeout) {
- setWithExpire(key, value, timeout, TimeUnit.SECONDS);
- }
- /**
- * 设置缓存值,如果key不存在,则设置成功,并指定过期时间
- *
- * @param key 键
- * @param value 值
- * @param timeout 过期时间
- * @param unit 时间单位
- * @return 是否设置成功
- */
- public Boolean setIfAbsent(String key, Object value, long timeout, TimeUnit unit) {
- validateKeyAndValue(key, value);
- validateTimeoutAndUnit(timeout, unit);
- return redisTemplate.opsForValue().setIfAbsent(key, value, timeout, unit);
- }
- /**
- * 设置缓存值,如果key不存在,则设置成功,并指定过期时间(单位:秒)
- *
- * @param key 键
- * @param value 值
- * @param timeout 过期时间
- * @return 是否设置成功
- */
- public Boolean setIfAbsent(String key, Object value, long timeout) {
- return setIfAbsent(key, value, timeout, TimeUnit.SECONDS);
- }
- /**
- * 获取缓存值并进行类型转换
- *
- * @param key 键
- * @param type 返回值的类型
- * @return 转换后的对象,若类型不匹配则抛出异常
- */
- public <T> T get(String key, Class<T> type) {
- Object value = redisTemplate.opsForValue().get(key);
- return convertValue(value, type);
- }
- /**
- * 获取缓存值并设置新值
- *
- * @param key 键
- * @param value 新值
- * @param type 返回值的类型
- * @param <T> 返回值的类型
- * @return 旧值,类型为 T
- */
- public <T> T getAndSet(String key, T value, Class<T> type) {
- Object oldValue = redisTemplate.opsForValue().getAndSet(key, value);
- return convertValue(oldValue, type);
- }
- /**
- * 根据 delta 值调整缓存中的数值
- *
- * @param key 键
- * @param delta 调整步长,正数表示增加,负数表示减少
- * @return 调整后的值
- */
- public Long changeByDelta(String key, long delta) {
- if (key == null) {
- throw new IllegalArgumentException("Key 不能为空!");
- }
- return redisTemplate.opsForValue().increment(key, delta);
- }
- /**
- * 验证键和值的合法性
- */
- private void validateKeyAndValue(String key, Object value) {
- if (key == null || value == null) {
- throw new IllegalArgumentException("Key 和 Value 不能为空!");
- }
- }
- /**
- * 验证超时时间和单位的合法性
- */
- private void validateTimeoutAndUnit(long timeout, TimeUnit unit) {
- if (timeout <= 0 || unit == null) {
- throw new IllegalArgumentException("超时时间必须大于 0,时间单位不能为空!");
- }
- }
- }
复制代码 3.RList.java
- package com.sunxiansheng.redis.utils;
- import org.springframework.data.redis.core.RedisTemplate;
- import java.util.ArrayList;
- import java.util.Collection;
- import java.util.List;
- /**
- * Description: Redis的List类型操作
- *
- * @Author sun
- * @Create 2024/11/14 14:50
- * @Version 1.0
- */
- public class RList extends RBase {
- /**
- * 构造器给父类注入RedisTemplate
- *
- * @param redisTemplate RedisTemplate实例
- */
- public RList(RedisTemplate<String, Object> redisTemplate) {
- super(redisTemplate);
- }
- /**
- * 左侧添加单个值
- *
- * @param key 键
- * @param value 要添加的值
- * @return 添加后的List长度
- */
- public Long leftPush(String key, Object value) {
- return redisTemplate.opsForList().leftPush(key, value);
- }
- /**
- * 左侧批量添加多个值(使用List参数方式)
- *
- * @param key 键
- * @param dataList 要添加的值列表
- * @param <V> 值类型
- * @return 添加后的List长度,调用方可以忽略返回值
- */
- public <V> Long leftPushAll(String key, List<V> dataList) {
- return redisTemplate.opsForList().leftPushAll(key, dataList.toArray());
- }
- /**
- * 左侧批量添加多个值(使用Collection参数方式)
- *
- * @param key 键
- * @param dataCollection 要添加的值集合
- * @param <V> 值类型
- * @return 添加后的List长度
- */
- public <V> Long leftPushAll(String key, Collection<V> dataCollection) {
- return redisTemplate.opsForList().leftPushAll(key, dataCollection.toArray());
- }
- /**
- * 右侧添加单个值
- *
- * @param key 键
- * @param value 要添加的值
- * @return 添加后的List长度
- */
- public Long rightPush(String key, Object value) {
- return redisTemplate.opsForList().rightPush(key, value);
- }
- /**
- * 右侧批量添加多个值(使用List参数方式)
- *
- * @param key 键
- * @param dataList 要添加的值列表
- * @param <V> 值类型
- * @return 添加后的List长度
- */
- public <V> Long rightPushAll(String key, List<V> dataList) {
- return redisTemplate.opsForList().rightPushAll(key, dataList.toArray());
- }
- /**
- * 右侧批量添加多个值(使用Collection参数方式)
- *
- * @param key 键
- * @param dataCollection 要添加的值集合
- * @param <V> 值类型
- * @return 添加后的List长度
- */
- public <V> Long rightPushAll(String key, Collection<V> dataCollection) {
- return redisTemplate.opsForList().rightPushAll(key, dataCollection.toArray());
- }
- /**
- * 根据值移除指定数量的匹配元素
- *
- * @param key 键
- * @param count 要移除的元素数量
- * @param value 要移除的值
- * @return 移除的元素数量
- */
- public Long removeByValue(String key, long count, Object value) {
- return redisTemplate.opsForList().remove(key, count, value);
- }
- /**
- * 从右侧弹出元素并转换为指定类型
- *
- * @param key 键
- * @param type 期望的返回值类型
- * @param <T> 泛型,表示期望的返回类型
- * @return 弹出并转换后的元素
- */
- public <T> T popRight(String key, Class<T> type) {
- Object value = redisTemplate.opsForList().rightPop(key);
- return convertValue(value, type);
- }
- /**
- * 从左侧弹出元素并转换为指定类型
- *
- * @param key 键
- * @param type 期望的返回值类型
- * @param <T> 泛型,表示期望的返回类型
- * @return 弹出并转换后的元素
- */
- public <T> T popLeft(String key, Class<T> type) {
- Object value = redisTemplate.opsForList().leftPop(key);
- return convertValue(value, type);
- }
- /**
- * 根据索引设置List中的值
- *
- * @param key 键
- * @param index 索引位置,从0开始
- * @param value 设置的值
- */
- public void set(String key, final long index, Object value) {
- redisTemplate.opsForList().set(key, index, value);
- }
- /**
- * 获取List中的所有数据,并将每个元素转换为指定类型
- *
- * @param key 键
- * @param type 要转换的值类型
- * @param <T> 要转换的值类型
- * @return 转换后的List
- */
- public <T> List<T> rangeAll(String key, Class<T> type) {
- List<Object> range = redisTemplate.opsForList().range(key, 0, -1);
- List<T> result = new ArrayList<>();
- if (range != null) {
- for (Object item : range) {
- result.add(convertValue(item, type));
- }
- }
- return result;
- }
- /**
- * 根据索引获取List中的元素并转换为指定类型
- *
- * @param key 键
- * @param index 索引位置,从0开始
- * @param type 期望的返回值类型
- * @param <T> 泛型,表示期望的返回类型
- * @return 转换后的元素
- */
- public <T> T getElementByIndex(String key, long index, Class<T> type) {
- Object value = redisTemplate.opsForList().index(key, index);
- return convertValue(value, type);
- }
- /**
- * 获取List的长度
- *
- * @param key 键
- * @return List的长度
- */
- public Long size(String key) {
- return redisTemplate.opsForList().size(key);
- }
- }
复制代码 4.RSet.java
- package com.sunxiansheng.redis.utils;
- import org.springframework.data.redis.core.RedisTemplate;
- import java.util.HashSet;
- import java.util.Set;
- /**
- * Description: Redis的Set类型操作
- *
- * @Author sun
- * @Create 2024/11/14 14:50
- * @Version 1.0
- */
- public class RSet extends RBase {
- /**
- * 构造器给父类注入RedisTemplate
- *
- * @param redisTemplate RedisTemplate实例
- */
- public RSet(RedisTemplate<String, Object> redisTemplate) {
- super(redisTemplate);
- }
- /**
- * 添加一个元素
- *
- * @param key 键
- * @param data 值
- * @return 添加成功的个数
- */
- public Long add(String key, Object data) {
- return redisTemplate.opsForSet().add(key, data);
- }
- /**
- * 批量添加元素,并返回添加成功的个数
- *
- * @param key 键
- * @param dataSet 值集合
- * @param <T> 添加的元素类型
- * @return 添加成功的个数
- */
- public <T> Long addBatch(String key, Set<T> dataSet) {
- return redisTemplate.opsForSet().add(key, dataSet.toArray());
- }
- /**
- * 移除特定的元素,并返回移除成功的个数
- *
- * @param key 键
- * @param dataSet 要移除的元素集合
- * @param <T> 要移除的元素类型
- * @return 移除成功的个数
- */
- public <T> Long remove(String key, Set<T> dataSet) {
- return redisTemplate.opsForSet().remove(key, dataSet.toArray());
- }
- /**
- * 获取集合,并将每个元素转换为指定类型
- *
- * @param key 键
- * @param type 集合中元素的目标类型
- * @param <T> 元素的类型
- * @return 转换后的集合
- */
- public <T> Set<T> members(String key, Class<T> type) {
- Set<Object> members = redisTemplate.opsForSet().members(key);
- Set<T> result = new HashSet<>();
- if (members != null) {
- for (Object member : members) {
- result.add(convertValue(member, type));
- }
- }
- return result;
- }
- /**
- * 判断集合中是否有该值
- *
- * @param key 键
- * @param data 值
- * @return 是否包含该值
- */
- public Boolean isMember(String key, Object data) {
- return redisTemplate.opsForSet().isMember(key, data);
- }
- /**
- * 获取set的长度
- *
- * @param key 键
- * @return 集合的长度
- */
- public Long size(String key) {
- return redisTemplate.opsForSet().size(key);
- }
- }
复制代码 5.RHash.java
- package com.sunxiansheng.redis.utils;
- import org.springframework.data.redis.core.RedisTemplate;
- import java.util.*;
- /**
- * Description: Redis的Hash类型操作
- *
- * @Author sun
- * @Create 2024/11/14 14:50
- * @Version 1.1
- */
- public class RHash extends RBase {
- /**
- * 构造器给父类注入RedisTemplate
- *
- * @param redisTemplate RedisTemplate实例
- */
- public RHash(RedisTemplate<String, Object> redisTemplate) {
- super(redisTemplate);
- }
- /**
- * 设置单个hash值
- *
- * @param key key
- * @param hashKey hashKey
- * @param hashValue hashValue
- */
- public void put(String key, String hashKey, Object hashValue) {
- redisTemplate.opsForHash().put(key, hashKey, hashValue);
- }
- /**
- * 设置多个hash值
- *
- * @param key key
- * @param map map
- */
- public void putAll(String key, Map<String, ?> map) {
- if (map == null || map.isEmpty()) {
- throw new IllegalArgumentException("Map不能为空!");
- }
- redisTemplate.opsForHash().putAll(key, map);
- }
- /**
- * 删除hash中的一些值
- *
- * @param key key
- * @param hashKeys hashKeys
- * @return 删除的个数
- */
- public Long delete(String key, List<String> hashKeys) {
- if (hashKeys == null || hashKeys.isEmpty()) {
- return 0L;
- }
- return redisTemplate.opsForHash().delete(key, hashKeys.toArray());
- }
- /**
- * 删除hash中的一个值
- *
- * @param key key
- * @param hashKey hashKey
- * @return 删除的个数
- */
- public Long delete(String key, String hashKey) {
- if (hashKey == null) {
- return 0L;
- }
- return redisTemplate.opsForHash().delete(key, hashKey);
- }
- /**
- * 获取单个hash值,并转换为指定类型
- *
- * @param key key
- * @param hashKey hashKey
- * @param type 类型
- * @param <T> 要转换的类型
- * @return hash值
- */
- public <T> T getOneMapValue(String key, String hashKey, Class<T> type) {
- if (hashKey == null) {
- return null;
- }
- Object object = redisTemplate.opsForHash().get(key, hashKey);
- return convertValue(object, type);
- }
- /**
- * 获取多个hash值,并转换为指定类型
- *
- * @param key Redis键
- * @param hashKeys Hash键集合
- * @param type 转换的目标类型
- * @param <T> 返回的泛型类型
- * @return 转换后的Hash对象集合
- */
- public <T> List<T> getMultiMapValue(String key, Collection<String> hashKeys, Class<T> type) {
- if (hashKeys == null || hashKeys.isEmpty()) {
- return Collections.emptyList();
- }
- Collection<Object> keys = new ArrayList<>(hashKeys);
- List<Object> objects = redisTemplate.opsForHash().multiGet(key, keys);
- List<T> result = new ArrayList<>();
- for (Object obj : objects) {
- result.add(convertValue(obj, type));
- }
- return result;
- }
- /**
- * 获取所有键值对,并将其转换为指定类型
- *
- * @param key 键
- * @param type 返回值的类型
- * @param <T> 值类型
- * @return 转换后的Map,键为String类型,值为T类型
- */
- public <T> Map<String, T> getAll(String key, Class<T> type) {
- Map<Object, Object> entries = redisTemplate.opsForHash().entries(key);
- if (entries.isEmpty()) {
- return Collections.emptyMap();
- }
- Map<String, T> result = new HashMap<>();
- for (Map.Entry<Object, Object> entry : entries.entrySet()) {
- if (entry.getKey() instanceof String) {
- String strKey = (String) entry.getKey();
- T value = convertValue(entry.getValue(), type);
- result.put(strKey, value);
- } else {
- throw new ClassCastException("Redis中Hash的键不是String类型:实际类型为 " + entry.getKey().getClass().getName());
- }
- }
- return result;
- }
- /**
- * 判断hash中是否存在某个键
- *
- * @param key key
- * @param hashKey hashKey
- * @return 是否存在
- */
- public Boolean hasHashKey(String key, String hashKey) {
- if (hashKey == null) {
- return false;
- }
- return redisTemplate.opsForHash().hasKey(key, hashKey);
- }
- }
复制代码 6.RSortedSet.java
- package com.sunxiansheng.redis.utils;
- import org.springframework.data.redis.core.RedisTemplate;
- import org.springframework.data.redis.core.ZSetOperations;
- import java.util.HashSet;
- import java.util.Set;
- import java.util.TreeSet;
- /**
- * Description: Redis的ZSet类型操作
- *
- * @Author sun
- * @Create 2024/11/14 14:50
- * @Version 1.0
- */
- public class RSortedSet extends RBase {
- /**
- * 构造器给父类注入RedisTemplate
- *
- * @param redisTemplate RedisTemplate实例
- */
- public RSortedSet(RedisTemplate<String, Object> redisTemplate) {
- super(redisTemplate);
- }
- /**
- * 添加一个元素,并设置分数
- *
- * @param key 键
- * @param data 元素
- * @param score 分数
- * @return 是否添加成功,成功返回true
- */
- public Boolean add(String key, Object data, double score) {
- return redisTemplate.opsForZSet().add(key, data, score);
- }
- /**
- * 自定义的数据分数类型,用于批量添加元素
- *
- * @param <T> 元素的类型
- */
- public static class DataScore<T> {
- /**
- * 数据
- */
- private T data;
- /**
- * 分数
- */
- private Double score;
- public DataScore() {
- }
- public DataScore(T data, Double score) {
- this.data = data;
- this.score = score;
- }
- public T getData() {
- return data;
- }
- public void setData(T data) {
- this.data = data;
- }
- public Double getScore() {
- return score;
- }
- public void setScore(Double score) {
- this.score = score;
- }
- }
- /**
- * 批量添加元素,并设置分数
- *
- * @param key 键
- * @param dataScores 自定义数据结构集合,包含元素及分数
- * @param <T> 元素的类型
- * @return 添加成功的元素数量
- */
- public <T> Long addBatch(String key, Set<DataScore<T>> dataScores) {
- // 将 Set<DataScore<T>> 转换为 Set<ZSetOperations.TypedTuple<Object>>
- Set<ZSetOperations.TypedTuple<Object>> tuples = new HashSet<>();
- for (DataScore<T> dataScore : dataScores) {
- tuples.add(new ZSetOperations.TypedTuple<Object>() {
- @Override
- public Object getValue() {
- return dataScore.getData(); // 调用 getData 方法
- }
- @Override
- public Double getScore() {
- return dataScore.getScore();
- }
- /**
- * 比较器,从大到小排序
- */
- @Override
- public int compareTo(ZSetOperations.TypedTuple<Object> o) {
- return Double.compare(o.getScore(), this.getScore());
- }
- });
- }
- // 添加到 Redis 的 ZSet
- return redisTemplate.opsForZSet().add(key, tuples);
- }
- /**
- * 移除特定的元素
- *
- * @param key 键
- * @param dataSet 要移除的元素集合
- * @param <T> 元素类型
- * @return 移除成功的元素数量
- */
- public <T> Long remove(String key, Set<T> dataSet) {
- return redisTemplate.opsForZSet().remove(key, dataSet.toArray());
- }
- /**
- * 删除指定分数范围的元素
- *
- * @param key 键
- * @param min 最小分数
- * @param max 最大分数
- * @return 删除成功的元素数量
- */
- public Long removeRangeByScore(String key, double min, double max) {
- return redisTemplate.opsForZSet().removeRangeByScore(key, min, max);
- }
- /**
- * 根据delta值调整指定元素的分数
- *
- * @param key 键
- * @param data 元素
- * @param delta 增加或减少的分数值
- * @return 调整后的分数
- */
- public Double changeByDelta(String key, Object data, double delta) {
- return redisTemplate.opsForZSet().incrementScore(key, data, delta);
- }
- /**
- * 获取全部ZSet元素(分数从大到小),并将值转换为指定类型
- *
- * @param key Redis键
- * @param type 元素的目标类型
- * @param <T> 元素类型
- * @return 转换后的ZSet集合,包含分值和对应的值
- */
- public <T> Set<ZSetOperations.TypedTuple<T>> reverseRangeWithScores(String key, Class<T> type) {
- // 获取 Redis 中的 ZSet 数据
- Set<ZSetOperations.TypedTuple<Object>> typedTuples = redisTemplate.opsForZSet().reverseRangeWithScores(key, 0, -1);
- // 使用 TreeSet 并提供自定义比较器,从大到小排序
- Set<ZSetOperations.TypedTuple<T>> result = new TreeSet<>((a, b) -> Double.compare(b.getScore(), a.getScore()));
- // 遍历并进行类型转换
- if (typedTuples != null) {
- for (ZSetOperations.TypedTuple<Object> tuple : typedTuples) {
- T value = convertValue(tuple.getValue(), type);
- Double score = tuple.getScore();
- result.add(new ZSetOperations.TypedTuple<T>() {
- @Override
- public T getValue() {
- return value;
- }
- @Override
- public Double getScore() {
- return score;
- }
- /**
- * 比较器,从大到小排序
- */
- @Override
- public int compareTo(ZSetOperations.TypedTuple<T> o) {
- return Double.compare(o.getScore(), this.getScore());
- }
- });
- }
- }
- return result;
- }
- /**
- * 获取指定元素的分数
- *
- * @param key 键
- * @param data 元素
- * @return 元素的分数
- */
- public Double score(String key, Object data) {
- return redisTemplate.opsForZSet().score(key, data);
- }
- /**
- * 获取指定元素的排名(从大到小)
- *
- * @param key 键
- * @param data 元素
- * @return 排名(从0开始)
- */
- public Long reverseRank(String key, Object data) {
- return redisTemplate.boundZSetOps(key).reverseRank(data);
- }
- /**
- * 获取ZSet中的元素总数
- *
- * @param key 键
- * @return 元素个数
- */
- public Long zCard(String key) {
- return redisTemplate.opsForZSet().zCard(key);
- }
- /**
- * 获取指定分数范围内的元素数量
- *
- * @param key 键
- * @param min 最小分数
- * @param max 最大分数
- * @return 元素数量
- */
- public Long count(String key, double min, double max) {
- return redisTemplate.opsForZSet().count(key, min, max);
- }
- }
复制代码 4.测试
1.创建测试模块
2.引入依靠
- <?xml version="1.0" encoding="UTF-8"?>
- <project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>com.sunxiansheng</groupId>
- <artifactId>sunrays-demo</artifactId>
- <version>1.0</version>
- </parent>
- <artifactId>common-redis-starter-demo</artifactId>
- <dependencies>
- <!-- 引入自定义的 common-redis-starter -->
- <dependency>
- <groupId>com.sunxiansheng</groupId>
- <artifactId>common-redis-starter</artifactId>
- <version>1.0</version>
- </dependency>
- <!-- 引入自定义的 common-log4j2-starter -->
- <dependency>
- <groupId>com.sunxiansheng</groupId>
- <artifactId>common-log4j2-starter</artifactId>
- <version>1.0</version>
- </dependency>
- <!-- 引入自定义的 common-web-starter -->
- <dependency>
- <groupId>com.sunxiansheng</groupId>
- <artifactId>common-web-starter</artifactId>
- <version>1.0</version>
- </dependency>
- </dependencies>
- </project>
复制代码 3.启动类
- package com.sunxiansheng.redis;
- import org.springframework.boot.SpringApplication;
- import org.springframework.boot.autoconfigure.SpringBootApplication;
- /**
- * Description: Redis启动类
- *
- * @Author sun
- * @Create 2024/11/15 20:56
- * @Version 1.0
- */
- @SpringBootApplication
- public class RedisApplication {
- public static void main(String[] args) {
- SpringApplication.run(RedisApplication.class, args);
- }
- }
复制代码
4.编写application.yml
- spring:
- redis:
- host: # Redis服务器地址
- port: # Redis服务器端口
- password: # Redis服务器密码
- database: 0 # 默认数据库为0号
- timeout: 1800000 # 连接超时时间是1800秒
- lettuce:
- pool:
- max-active: 20 # 最大活跃连接数,使用负值表示没有限制
- max-wait: -1 # 最大等待时间,单位为毫秒,使用负值表示没有限制
- max-idle: 10 # 最大空闲连接数
- min-idle: 0 # 最小空闲连接数
复制代码 5.测试
1.RStringController.java
- package com.sunxiansheng.redis.controller;
- import com.sunxiansheng.redis.utils.RString;
- import org.springframework.web.bind.annotation.*;
- import javax.annotation.Resource;
- import java.util.concurrent.TimeUnit;
- /**
- * Description: 测试 RString 工具类的 Controller
- *
- * @Author sun
- * @Create 2024/11/14 15:20
- * @Version 1.0
- */
- @RestController
- @RequestMapping("/rstring")
- public class RStringController {
- @Resource
- private RString rString;
- /**
- * 设置缓存值
- */
- @PostMapping("/set")
- public String set(@RequestParam String key, @RequestParam Long value) {
- rString.set(key, value);
- return "Value set successfully!";
- }
- /**
- * 设置缓存值并设置过期时间
- */
- @PostMapping("/setWithExpire")
- public String setWithExpire(@RequestParam String key,
- @RequestParam Long value,
- @RequestParam long timeout) {
- rString.setWithExpire(key, value, timeout);
- return "Value set with expiration successfully!";
- }
- /**
- * 设置缓存值并设置过期时间(自定义时间单位)
- */
- @PostMapping("/setWithExpireUnit")
- public String setWithExpireUnit(@RequestParam String key,
- @RequestParam Long value,
- @RequestParam long timeout) {
- rString.setWithExpire(key, value, timeout, TimeUnit.DAYS);
- return "Value set with custom expiration successfully!";
- }
- /**
- * 设置缓存值,如果key不存在,则设置成功
- */
- @PostMapping("/setIfAbsent")
- public String setIfAbsent(@RequestParam String key,
- @RequestParam Long value,
- @RequestParam long timeout) {
- boolean result = rString.setIfAbsent(key, value, timeout);
- return result ? "Value set successfully!" : "Key already exists!";
- }
- /**
- * 获取缓存值
- */
- @GetMapping("/get")
- public Long get(@RequestParam String key) {
- return rString.get(key, Long.class);
- }
- /**
- * 获取缓存值并设置新值
- */
- @PostMapping("/getAndSet")
- public Long getAndSet(@RequestParam String key, @RequestParam Long value) {
- return rString.getAndSet(key, value, Long.class);
- }
- /**
- * 根据 delta 值调整缓存中的数值
- */
- @PostMapping("/changeByDelta")
- public Long changeByDelta(@RequestParam String key, @RequestParam long delta) {
- return rString.changeByDelta(key, delta);
- }
- }
复制代码 2.RListController.java
- package com.sunxiansheng.redis.controller;
- import com.sunxiansheng.redis.utils.RList;
- import lombok.AllArgsConstructor;
- import lombok.Data;
- import lombok.NoArgsConstructor;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.web.bind.annotation.*;
- import java.util.List;
- /**
- * 测试 RList 工具类的 Controller
- *
- * @Author sun
- * @Create 2024/11/14 16:00
- * @Version 1.0
- */
- @RestController
- @RequestMapping("/rlist")
- public class RListController {
- @Autowired
- private RList rList;
- /**
- * 左侧添加单个值
- */
- @PostMapping("/leftPush")
- public String leftPush(@RequestParam String key, @RequestBody User user) {
- rList.leftPush(key, user);
- return "User added to the left of the list.";
- }
- /**
- * 左侧批量添加多个值
- */
- @PostMapping("/leftPushAll")
- public String leftPushAll(@RequestParam String key, @RequestBody List<User> users) {
- rList.leftPushAll(key, users);
- return "Users added to the left of the list.";
- }
- /**
- * 右侧添加单个值
- */
- @PostMapping("/rightPush")
- public String rightPush(@RequestParam String key, @RequestBody User user) {
- rList.rightPush(key, user);
- return "User added to the right of the list.";
- }
- /**
- * 右侧批量添加多个值
- */
- @PostMapping("/rightPushAll")
- public String rightPushAll(@RequestParam String key, @RequestBody List<User> users) {
- rList.rightPushAll(key, users);
- return "Users added to the right of the list.";
- }
- /**
- * 根据索引设置List中的值
- */
- @PutMapping("/set")
- public String set(@RequestParam String key, @RequestParam int index, @RequestBody User user) {
- rList.set(key, index, user);
- return "User updated at index " + index;
- }
- /**
- * 获取List中的所有数据
- */
- @GetMapping("/rangeAll")
- public List<User> rangeAll(@RequestParam String key) {
- return rList.rangeAll(key, User.class);
- }
- /**
- * 根据索引获取List中的元素
- */
- @GetMapping("/getElementByIndex")
- public User getElementByIndex(@RequestParam String key, @RequestParam int index) {
- return rList.getElementByIndex(key, index, User.class);
- }
- /**
- * 获取List的长度
- */
- @GetMapping("/size")
- public Long size(@RequestParam String key) {
- return rList.size(key);
- }
- /**
- * 从右侧弹出元素
- */
- @DeleteMapping("/popRight")
- public User popRight(@RequestParam String key) {
- return rList.popRight(key, User.class);
- }
- /**
- * 从左侧弹出元素
- */
- @DeleteMapping("/popLeft")
- public User popLeft(@RequestParam String key) {
- return rList.popLeft(key, User.class);
- }
- /**
- * 根据值移除指定数量的匹配元素
- */
- @DeleteMapping("/removeByValue")
- public String removeByValue(@RequestParam String key, @RequestParam int count, @RequestBody User user) {
- Long removedCount = rList.removeByValue(key, count, user);
- return removedCount + " matching users removed.";
- }
- }
- /**
- * 简单的自定义类型 User
- *
- * @Author sun
- * @Create 2024/11/14 15:50
- * @Version 1.0
- */
- @NoArgsConstructor
- @Data
- @AllArgsConstructor
- class User implements java.io.Serializable {
- private String id;
- private String name;
- }
复制代码 3.RSetController.java
- package com.sunxiansheng.redis.controller;
- import com.sunxiansheng.redis.utils.RSet;
- import lombok.AllArgsConstructor;
- import lombok.Data;
- import lombok.NoArgsConstructor;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.web.bind.annotation.*;
- import java.io.Serializable;
- import java.util.Set;
- /**
- * Description: RSet的测试Controller
- *
- * @Author sun
- * @Create 2024/11/15
- * @Version 1.0
- */
- @RestController
- @RequestMapping("/rset")
- public class RSetController {
- @Autowired
- private RSet rSet;
- /**
- * 静态内部类表示简单的自定义对象
- */
- @Data
- @NoArgsConstructor
- @AllArgsConstructor
- public static class Element implements Serializable {
- private Long id;
- private String name;
- }
- /**
- * 添加一个元素
- */
- @PostMapping("/add")
- public Long add(@RequestParam String key, @RequestBody Element element) {
- return rSet.add(key, element);
- }
- /**
- * 批量添加元素
- */
- @PostMapping("/addBatch")
- public Long addBatch(@RequestParam String key, @RequestBody Set<Element> elements) {
- return rSet.addBatch(key, elements);
- }
- /**
- * 移除元素
- */
- @PostMapping("/remove")
- public Long remove(@RequestParam String key, @RequestBody Set<Element> elements) {
- return rSet.remove(key, elements);
- }
- /**
- * 获取集合
- */
- @GetMapping("/members")
- public Set<Element> members(@RequestParam String key) {
- return rSet.members(key, Element.class);
- }
- /**
- * 判断是否包含某元素
- */
- @GetMapping("/isMember")
- public Boolean isMember(@RequestParam String key, @RequestBody Element element) {
- return rSet.isMember(key, element);
- }
- /**
- * 获取集合大小
- */
- @GetMapping("/size")
- public Long size(@RequestParam String key) {
- return rSet.size(key);
- }
- }
复制代码 4.RHashController.java
- package com.sunxiansheng.redis.controller;
- import com.sunxiansheng.redis.utils.RHash;
- import lombok.AllArgsConstructor;
- import lombok.Data;
- import lombok.NoArgsConstructor;
- import org.springframework.web.bind.annotation.*;
- import java.util.*;
- @RestController
- @RequestMapping("/rhash")
- public class RHashController {
- private final RHash rHash;
- public RHashController(RHash rHash) {
- this.rHash = rHash;
- }
- @NoArgsConstructor
- @AllArgsConstructor
- @Data
- public static class User {
- private Long id;
- private String name;
- private Integer age;
- }
- /**
- * 设置单个hash值
- */
- @PostMapping("/put")
- public void put(@RequestParam String key, @RequestParam String hashKey, @RequestBody User user) {
- rHash.put(key, hashKey, user);
- }
- /**
- * 设置多个hash值
- */
- @PostMapping("/putAll")
- public void putAll(@RequestParam String key, @RequestBody Map<String, User> userMap) {
- rHash.putAll(key, userMap);
- }
- /**
- * 删除hash中的多个值
- */
- @DeleteMapping("/deleteMultiple")
- public Long deleteMultiple(@RequestParam String key, @RequestBody List<String> hashKeys) {
- return rHash.delete(key, hashKeys);
- }
- /**
- * 删除hash中的单个值
- */
- @DeleteMapping("/deleteSingle")
- public Long deleteSingle(@RequestParam String key, @RequestParam String hashKey) {
- return rHash.delete(key, hashKey);
- }
- /**
- * 获取单个hash值并转换为指定类型
- */
- @GetMapping("/getOne")
- public User getOneMapValue(@RequestParam String key, @RequestParam String hashKey) {
- return rHash.getOneMapValue(key, hashKey, User.class);
- }
- /**
- * 获取多个hash值并转换为指定类型
- */
- @GetMapping("/getMulti")
- public List<User> getMultiMapValue(@RequestParam String key, @RequestBody List<String> hashKeys) {
- return rHash.getMultiMapValue(key, hashKeys, User.class);
- }
- /**
- * 获取所有键值对并转换为指定类型
- */
- @GetMapping("/getAll")
- public Map<String, User> getAll(@RequestParam String key) {
- return rHash.getAll(key, User.class);
- }
- /**
- * 判断hash中是否存在某个键
- */
- @GetMapping("/hasHashKey")
- public Boolean hasHashKey(@RequestParam String key, @RequestParam String hashKey) {
- return rHash.hasHashKey(key, hashKey);
- }
- }
复制代码 5.RSortedSetController.java
- package com.sunxiansheng.redis.controller;
- import com.sunxiansheng.redis.utils.RSortedSet;
- import lombok.AllArgsConstructor;
- import lombok.Data;
- import lombok.NoArgsConstructor;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.data.redis.core.ZSetOperations;
- import org.springframework.web.bind.annotation.*;
- import java.util.Set;
- /**
- * Description: 测试 RSortedSet 工具类
- *
- * @Author sun
- * @Create 2024/11/16
- * @Version 1.0
- */
- @RestController
- @RequestMapping("/rsortedset")
- public class RSortedSetController {
- @Autowired
- private RSortedSet rSortedSet;
- // 自定义类型
- @Data
- @NoArgsConstructor
- @AllArgsConstructor
- public static class CustomValue {
- private Long id;
- private String name;
- }
- @PostMapping("/add")
- public Boolean add(@RequestParam String key, @RequestBody CustomValue value, @RequestParam double score) {
- return rSortedSet.add(key, value, score);
- }
- @PostMapping("/addBatch")
- public Long addBatch(@RequestParam String key, @RequestBody Set<RSortedSet.DataScore<CustomValue>> dataScores) {
- return rSortedSet.addBatch(key, dataScores);
- }
- @PostMapping("/remove")
- public Long remove(@RequestParam String key, @RequestBody Set<CustomValue> values) {
- return rSortedSet.remove(key, values);
- }
- @PostMapping("/removeRangeByScore")
- public Long removeRangeByScore(@RequestParam String key, @RequestParam double min, @RequestParam double max) {
- return rSortedSet.removeRangeByScore(key, min, max);
- }
- @PostMapping("/changeByDelta")
- public Double changeByDelta(@RequestParam String key, @RequestBody CustomValue value, @RequestParam double delta) {
- return rSortedSet.changeByDelta(key, value, delta);
- }
- @GetMapping("/reverseRangeWithScores")
- public Set<ZSetOperations.TypedTuple<CustomValue>> reverseRangeWithScores(@RequestParam String key) {
- return rSortedSet.reverseRangeWithScores(key, CustomValue.class);
- }
- @GetMapping("/score")
- public Double score(@RequestParam String key, @RequestBody CustomValue value) {
- return rSortedSet.score(key, value);
- }
- @GetMapping("/reverseRank")
- public Long reverseRank(@RequestParam String key, @RequestBody CustomValue value) {
- return rSortedSet.reverseRank(key, value);
- }
- @GetMapping("/zCard")
- public Long zCard(@RequestParam String key) {
- return rSortedSet.zCard(key);
- }
- @GetMapping("/count")
- public Long count(@RequestParam String key, @RequestParam double min, @RequestParam double max) {
- return rSortedSet.count(key, min, max);
- }
- }
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |