当前位置: 首页 > news >正文

后端开发 Springboot整合Redis Spring Data Redis 模板

目录

redis 配置 RedisConfig 类

完整代码

代码讲解

1. 类定义和注解

2. 定义 RedisTemplate Bean

3. 配置 JSON 序列化

4. 配置 Redis 的 key 和 value 序列化方式

5. 完成配置并返回 RedisTemplate

总结

redis 服务接口实现类

类级别

注入 RedisTemplate

常用 Redis 操作

1. 设置和获取过期时间

2. 获取 Redis 键

3. 操作字符串类型数据

4. 操作哈希类型数据

5. 操作列表类型数据

6. 操作集合类型数据

7. 操作有序集合类型数据

其他方法

总结

Redis 模板注释版本


redis 配置 RedisConfig 类

完整代码

package com.ican.config;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 com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
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;/*** Redis配置** @author Dduo* @date 2024/12/02 15:40**/
@Configuration
public class RedisConfig {@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {RedisTemplate<String, Object> template = new RedisTemplate<>();template.setConnectionFactory(redisConnectionFactory);// Json序列化配置Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);ObjectMapper objectMapper = new ObjectMapper();// 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和publicobjectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);// 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会跑出异常objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);jackson2JsonRedisSerializer.setObjectMapper(objectMapper);// String序列化StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();// 使用String来序列化和反序列化keytemplate.setKeySerializer(stringRedisSerializer);// 使用Jackson来序列化和反序列化valuetemplate.setValueSerializer(jackson2JsonRedisSerializer);// Hash的key采用String的序列化方式template.setHashKeySerializer(stringRedisSerializer);// Hash的value采用Jackson的序列化方式template.setHashValueSerializer(jackson2JsonRedisSerializer);template.afterPropertiesSet();return template;}}

代码讲解

1. 类定义和注解
java复制代码
@Configuration
public class RedisConfig {
  • @Configuration 注解表示这是一个配置类,它会被 Spring 容器自动扫描并注册为一个 Bean。
2. 定义 RedisTemplate Bean
java复制代码
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {RedisTemplate<String, Object> template = new RedisTemplate<>();template.setConnectionFactory(redisConnectionFactory);
  • @Bean 注解告诉 Spring 这是一个需要管理的 Bean。方法 redisTemplate 创建并配置一个 RedisTemplate,该模板用于在 Redis 中执行操作。
  • RedisConnectionFactory 是 Redis 连接的工厂,Spring Data Redis 使用它来创建与 Redis 服务器的连接。
3. 配置 JSON 序列化
java复制代码
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
  • 这里使用了 Jackson2JsonRedisSerializer 来配置 Redis 中存储的数据的序列化方式,将对象转为 JSON 格式进行存储。
  • ObjectMapper 是 Jackson 提供的类,用于将 Java 对象转为 JSON。
  • setVisibility 方法设置哪些 Java 类的字段应该被序列化,JsonAutoDetect.Visibility.ANY 表示包括所有字段(私有、保护和公共字段都包括)。
  • activateDefaultTyping 方法指定序列化输入的类型,NON_FINAL 表示可以序列化非 final 修饰的类型(例如 String、Integer 是 final 的,无法序列化)。
  • JsonTypeInfo.As.PROPERTY 指定类型信息应该作为 JSON 属性存储在序列化对象中。
4. 配置 Redis 的 key 和 value 序列化方式
java复制代码
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
template.setKeySerializer(stringRedisSerializer);
template.setValueSerializer(jackson2JsonRedisSerializer);
template.setHashKeySerializer(stringRedisSerializer);
template.setHashValueSerializer(jackson2JsonRedisSerializer);
  • StringRedisSerializer 用来将 Redis 的键(key)序列化成字符串格式。
  • jackson2JsonRedisSerializer 用于将 Redis 的值(value)序列化为 JSON 格式。
  • 这里也配置了 Redis 的哈希表(hash)数据类型,指定哈希的键和值的序列化方式。
5. 完成配置并返回 RedisTemplate
java复制代码
template.afterPropertiesSet();
return template;
  • afterPropertiesSet 方法是 RedisTemplate 的初始化方法,用来确认所有的属性都已经设置完成。
  • 最后返回配置好的 RedisTemplate 实例。

总结

这段代码完成了如下几项工作:

  • 配置 RedisTemplate 连接工厂,以便与 Redis 进行通信。
  • 配置了 JSON 序列化和反序列化机制,使得 Redis 中的值使用 JSON 格式存储。
  • 配置了 Redis 键(key)使用字符串序列化,值(value)使用 Jackson 序列化。
  • 配置了 Redis 哈希表的键和值的序列化方式。

通过这些配置,可以让应用程序与 Redis 进行无缝的数据存取操作,且数据在存储到 Redis 时被序列化为 JSON 格式,使得存取更加灵活和易于处理。

redis 服务接口实现类

package com.ican.service;import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;/*** Redis服务接口实现类** @author Dduo*/
@Service
@SuppressWarnings("all")
public class RedisService {@Resourceprivate RedisTemplate<String, Object> redisTemplate;public Boolean setExpire(String key, long timeout, TimeUnit timeUnit) {return redisTemplate.expire(key, timeout, timeUnit);}public Long getExpire(String key, TimeUnit timeUnit) {return redisTemplate.getExpire(key, timeUnit);}public Collection<String> getKeys(String pattern) {return redisTemplate.keys(pattern);}public Boolean hasKey(String key) {return redisTemplate.hasKey(key);}public <T> void setObject(String key, T value) {redisTemplate.opsForValue().set(key, value);}public <T> void setObject(String key, T value, long timeout, TimeUnit timeUnit) {redisTemplate.opsForValue().set(key, value, timeout, timeUnit);}public <T> T getObject(String key) {return (T) redisTemplate.opsForValue().get(key);}public Boolean deleteObject(String key) {return redisTemplate.delete(key);}public Long deleteObject(List<String> keys) {return redisTemplate.delete(keys);}public Long incr(String key, long delta) {return redisTemplate.opsForValue().increment(key, delta);}public Long decr(String key, long delta) {return redisTemplate.opsForValue().decrement(key, -delta);}public <T> void setHash(String key, String hashKey, T value) {redisTemplate.opsForHash().put(key, hashKey, value);}public <T> Boolean setHash(String key, String hashKey, T value, long timeout, TimeUnit timeUnit) {redisTemplate.opsForHash().put(key, hashKey, value);return setExpire(key, timeout, timeUnit);}public <T> void setHashAll(String key, Map<String, T> map) {redisTemplate.opsForHash().putAll(key, map);}public <T> Boolean setHashAll(String key, Map<String, T> map, long timeout, TimeUnit timeUnit) {redisTemplate.opsForHash().putAll(key, map);return setExpire(key, timeout, timeUnit);}public <T> T getHash(String key, String hashKey) {return (T) redisTemplate.opsForHash().get(key, hashKey);}public Map getHashAll(String key) {return redisTemplate.opsForHash().entries(key);}public <T> void deleteHash(String key, T... hashKeys) {redisTemplate.opsForHash().delete(key, hashKeys);}public Boolean hasHashValue(String key, String hashKey) {return redisTemplate.opsForHash().hasKey(key, hashKey);}public Long incrHash(String key, String hashKey, Long delta) {return redisTemplate.opsForHash().increment(key, hashKey, delta);}public Long decrHash(String key, String hashKey, Long delta) {return redisTemplate.opsForHash().increment(key, hashKey, -delta);}public <T> Long setList(String key, T value) {return redisTemplate.opsForList().rightPush(key, value);}public <T> Long setList(String key, T value, long timeout, TimeUnit timeUnit) {Long count = redisTemplate.opsForList().rightPush(key, value);setExpire(key, timeout, timeUnit);return count;}public <T> Long setListAll(String key, T... values) {return redisTemplate.opsForList().rightPushAll(key, values);}public <T> Long setListAll(String key, long timeout, TimeUnit timeUnit, T... values) {Long count = redisTemplate.opsForList().rightPushAll(key, values);setExpire(key, timeout, timeUnit);return count;}public <T> List<T> getList(String key, long start, long end) {List<T> result = (List<T>) redisTemplate.opsForList().range(key, start, end);return result;}public <T> T getListByIndex(String key, long index) {return (T) redisTemplate.opsForList().index(key, index);}public Long getListSize(String key) {return redisTemplate.opsForList().size(key);}public <T> Long deleteList(String key, long count, T value) {return redisTemplate.opsForList().remove(key, count, value);}public <T> Long setSet(String key, T... values) {return redisTemplate.opsForSet().add(key, values);}public <T> Long setSet(String key, long timeout, TimeUnit timeUnit, T... values) {Long count = redisTemplate.opsForSet().add(key, values);setExpire(key, timeout, timeUnit);return count;}public <T> Set<T> getSet(String key) {Set<T> result = (Set<T>) redisTemplate.opsForSet().members(key);return result;}public <T> Long deleteSet(String key, T... values) {return redisTemplate.opsForSet().remove(key, values);}public <T> Boolean hasSetValue(String key, T value) {return redisTemplate.opsForSet().isMember(key, value);}public Long getSetSize(String key) {return redisTemplate.opsForSet().size(key);}public <T> Double incrZet(String key, T value, Double score) {return redisTemplate.opsForZSet().incrementScore(key, value, score);}public <T> Double decrZet(String key, T value, Double score) {return redisTemplate.opsForZSet().incrementScore(key, value, -score);}public <T> Long deleteZetScore(String key, T... values) {return redisTemplate.opsForZSet().remove(key, values);}public Map<Object, Double> zReverseRangeWithScore(String key, long start, long end) {return redisTemplate.opsForZSet().reverseRangeWithScores(key, start, end).stream().collect(Collectors.toMap(ZSetOperations.TypedTuple::getValue, ZSetOperations.TypedTuple::getScore));}public <T> Double getZsetScore(String key, T value) {return redisTemplate.opsForZSet().score(key, value);}public Map<Object, Double> getZsetAllScore(String key) {return Objects.requireNonNull(redisTemplate.opsForZSet().rangeWithScores(key, 0, -1)).stream().collect(Collectors.toMap(ZSetOperations.TypedTuple::getValue, ZSetOperations.TypedTuple::getScore));}}

这段代码实现了一个 RedisService 类,提供了与 Redis 数据库交互的多种方法,涵盖了对 Redis 的常见操作,包括字符串、哈希、列表、集合、有序集合等数据类型的增删改查功能,并支持设置过期时间。以下是该类各部分的详细讲解:

类级别

java复制代码
@Service
@SuppressWarnings("all")
public class RedisService {
  • @Service 注解表示这是一个 Spring 服务类,Spring 会将其注册为一个 Bean 进行管理,供应用程序其他部分使用。
  • @SuppressWarnings("all") 用来抑制编译器的警告,通常是为了避免不必要的警告信息。

注入 RedisTemplate

java复制代码
@Resource
private RedisTemplate<String, Object> redisTemplate;
  • @Resource 注解表示自动注入 RedisTemplate,这是 Spring Data Redis 提供的用于操作 Redis 的模板类。通过它可以执行 Redis 操作。
  • RedisTemplate<String, Object> 表示 Redis 键的类型为 String,值的类型为 Object,这允许操作 Redis 中的多种数据类型。

常用 Redis 操作

1. 设置和获取过期时间
java复制代码
public Boolean setExpire(String key, long timeout, TimeUnit timeUnit) {return redisTemplate.expire(key, timeout, timeUnit);
}public Long getExpire(String key, TimeUnit timeUnit) {return redisTemplate.getExpire(key, timeUnit);
}
  • setExpire 设置 Redis 键的过期时间。
  • getExpire 获取 Redis 键的剩余过期时间。
2. 获取 Redis 键
java复制代码
public Collection<String> getKeys(String pattern) {return redisTemplate.keys(pattern);
}public Boolean hasKey(String key) {return redisTemplate.hasKey(key);
}
  • getKeys 获取符合给定模式的所有键。
  • hasKey 检查 Redis 中是否存在指定的键。
3. 操作字符串类型数据
java复制代码
public <T> void setObject(String key, T value) {redisTemplate.opsForValue().set(key, value);
}public <T> T getObject(String key) {return (T) redisTemplate.opsForValue().get(key);
}public Long incr(String key, long delta) {return redisTemplate.opsForValue().increment(key, delta);
}public Long decr(String key, long delta) {return redisTemplate.opsForValue().decrement(key, -delta);
}
  • setObjectgetObject 分别用于设置和获取 Redis 中的字符串类型数据。
  • incrdecr 用于对字符串类型的值进行递增和递减操作。
4. 操作哈希类型数据
java复制代码
public <T> void setHash(String key, String hashKey, T value) {redisTemplate.opsForHash().put(key, hashKey, value);
}public <T> T getHash(String key, String hashKey) {return (T) redisTemplate.opsForHash().get(key, hashKey);
}public Map getHashAll(String key) {return redisTemplate.opsForHash().entries(key);
}
  • setHashgetHash 用于设置和获取 Redis 中哈希类型的数据。
  • getHashAll 获取哈希表的所有键值对。
5. 操作列表类型数据
java复制代码
public <T> Long setList(String key, T value) {return redisTemplate.opsForList().rightPush(key, value);
}public <T> List<T> getList(String key, long start, long end) {List<T> result = (List<T>) redisTemplate.opsForList().range(key, start, end);return result;
}
  • setList 用于将元素添加到 Redis 列表的末尾。
  • getList 用于获取列表中的指定范围的元素。
6. 操作集合类型数据
java复制代码
public <T> Long setSet(String key, T... values) {return redisTemplate.opsForSet().add(key, values);
}public <T> Set<T> getSet(String key) {Set<T> result = (Set<T>) redisTemplate.opsForSet().members(key);return result;
}
  • setSet 用于将元素添加到 Redis 集合。
  • getSet 用于获取 Redis 集合中的所有元素。
7. 操作有序集合类型数据
java复制代码
public <T> Double incrZet(String key, T value, Double score) {return redisTemplate.opsForZSet().incrementScore(key, value, score);
}public Map<Object, Double> zReverseRangeWithScore(String key, long start, long end) {return redisTemplate.opsForZSet().reverseRangeWithScores(key, start, end).stream().collect(Collectors.toMap(ZSetOperations.TypedTuple::getValue, ZSetOperations.TypedTuple::getScore));
}
  • incrZet 用于增减有序集合元素的分数。
  • zReverseRangeWithScore 获取有序集合中的指定范围的元素和对应的分数,并以 Map 返回。

其他方法

  • deleteObjectdeleteList 等方法用于删除 Redis 中的键值对、列表中的元素等。
  • hasHashValue 用于检查 Redis 哈希表中是否存在指定的值。
  • deleteSetdeleteZetScore 用于删除集合和有序集合中的元素。

总结

RedisService 类封装了多种与 Redis 交互的常用方法,包括对不同数据类型的操作(字符串、哈希、列表、集合、有序集合等)。这些方法提供了简洁的接口,使得应用程序可以方便地使用 Redis 作为缓存和数据存储系统。并且,部分方法支持设置过期时间,使得存储的数据可以自动失效。

Redis 模板注释版本

package com.ican.service;import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;/*** Redis服务接口实现类** @author Dduo*/
@Service
@SuppressWarnings("all")
public class RedisService {// 注入 RedisTemplate@Resourceprivate RedisTemplate<String, Object> redisTemplate;/*** 设置 Redis 键的过期时间** @param key       Redis 键* @param timeout   过期时间* @param timeUnit  时间单位* @return 是否成功设置过期时间*/public Boolean setExpire(String key, long timeout, TimeUnit timeUnit) {return redisTemplate.expire(key, timeout, timeUnit);}/*** 获取 Redis 键的剩余过期时间** @param key       Redis 键* @param timeUnit  时间单位* @return 剩余过期时间(单位为 timeUnit)*/public Long getExpire(String key, TimeUnit timeUnit) {return redisTemplate.getExpire(key, timeUnit);}/*** 获取符合给定模式的所有 Redis 键** @param pattern 键的模式(可以使用通配符)* @return 键的集合*/public Collection<String> getKeys(String pattern) {return redisTemplate.keys(pattern);}/*** 检查 Redis 中是否存在指定的键** @param key Redis 键* @return 是否存在该键*/public Boolean hasKey(String key) {return redisTemplate.hasKey(key);}/*** 设置 Redis 中的字符串类型数据** @param key   Redis 键* @param value 存储的值* @param <T>   值的类型*/public <T> void setObject(String key, T value) {redisTemplate.opsForValue().set(key, value);}/*** 设置 Redis 中的字符串类型数据,并设置过期时间** @param key       Redis 键* @param value     存储的值* @param timeout   过期时间* @param timeUnit  时间单位* @param <T>       值的类型*/public <T> void setObject(String key, T value, long timeout, TimeUnit timeUnit) {redisTemplate.opsForValue().set(key, value, timeout, timeUnit);}/*** 获取 Redis 中的字符串类型数据** @param key Redis 键* @param <T> 值的类型* @return Redis 存储的值*/public <T> T getObject(String key) {return (T) redisTemplate.opsForValue().get(key);}/*** 删除 Redis 中的字符串类型数据** @param key Redis 键* @return 删除成功返回 true,否则返回 false*/public Boolean deleteObject(String key) {return redisTemplate.delete(key);}/*** 删除 Redis 中的字符串类型数据(支持批量删除)** @param keys Redis 键的集合* @return 被删除的键的数量*/public Long deleteObject(List<String> keys) {return redisTemplate.delete(keys);}/*** 对 Redis 中的字符串类型值进行递增操作** @param key   Redis 键* @param delta 增加的值* @return 增加后的值*/public Long incr(String key, long delta) {return redisTemplate.opsForValue().increment(key, delta);}/*** 对 Redis 中的字符串类型值进行递减操作** @param key   Redis 键* @param delta 减少的值* @return 减少后的值*/public Long decr(String key, long delta) {return redisTemplate.opsForValue().decrement(key, -delta);}/*** 设置 Redis 中哈希类型的数据** @param key     Redis 键* @param hashKey 哈希键* @param value   存储的值* @param <T>     值的类型*/public <T> void setHash(String key, String hashKey, T value) {redisTemplate.opsForHash().put(key, hashKey, value);}/*** 设置 Redis 中哈希类型的数据,并设置过期时间** @param key       Redis 键* @param hashKey   哈希键* @param value     存储的值* @param timeout   过期时间* @param timeUnit  时间单位* @param <T>       值的类型* @return 是否成功设置过期时间*/public <T> Boolean setHash(String key, String hashKey, T value, long timeout, TimeUnit timeUnit) {redisTemplate.opsForHash().put(key, hashKey, value);return setExpire(key, timeout, timeUnit);}/*** 设置 Redis 中哈希类型的数据(批量设置)** @param key Redis 键* @param map 存储的键值对集合* @param <T> 值的类型*/public <T> void setHashAll(String key, Map<String, T> map) {redisTemplate.opsForHash().putAll(key, map);}/*** 设置 Redis 中哈希类型的数据(批量设置),并设置过期时间** @param key       Redis 键* @param map       存储的键值对集合* @param timeout   过期时间* @param timeUnit  时间单位* @param <T>       值的类型* @return 是否成功设置过期时间*/public <T> Boolean setHashAll(String key, Map<String, T> map, long timeout, TimeUnit timeUnit) {redisTemplate.opsForHash().putAll(key, map);return setExpire(key, timeout, timeUnit);}/*** 获取 Redis 中哈希类型的数据** @param key     Redis 键* @param hashKey 哈希键* @param <T>     值的类型* @return Redis 存储的值*/public <T> T getHash(String key, String hashKey) {return (T) redisTemplate.opsForHash().get(key, hashKey);}/*** 获取 Redis 中哈希类型的所有数据** @param key Redis 键* @return 键值对集合*/public Map getHashAll(String key) {return redisTemplate.opsForHash().entries(key);}/*** 删除 Redis 中哈希类型的数据** @param key       Redis 键* @param hashKeys  哈希键* @param <T>       值的类型*/public <T> void deleteHash(String key, T... hashKeys) {redisTemplate.opsForHash().delete(key, hashKeys);}/*** 判断 Redis 中是否存在指定哈希类型的数据** @param key     Redis 键* @param hashKey 哈希键* @return 是否存在指定哈希键*/public Boolean hasHashValue(String key, String hashKey) {return redisTemplate.opsForHash().hasKey(key, hashKey);}/*** 对 Redis 中哈希类型的数据进行递增操作** @param key     Redis 键* @param hashKey 哈希键* @param delta   增加的值* @return 增加后的值*/public Long incrHash(String key, String hashKey, Long delta) {return redisTemplate.opsForHash().increment(key, hashKey, delta);}/*** 对 Redis 中哈希类型的数据进行递减操作** @param key     Redis 键* @param hashKey 哈希键* @param delta   减少的值* @return 减少后的值*/public Long decrHash(String key, String hashKey, Long delta) {return redisTemplate.opsForHash().increment(key, hashKey, -delta);}/*** 将数据添加到 Redis 中的列表类型** @param key   Redis 键* @param value 存储的值* @param <T>   值的类型* @return 添加后的列表长度*/public <T> Long setList(String key, T value) {return redisTemplate.opsForList().rightPush(key, value);}/*** 将数据添加到 Redis 中的列表类型,并设置过期时间** @param key       Redis 键* @param value     存储的值* @param timeout   过期时间* @param timeUnit  时间单位* @param <T>       值的类型* @return 添加后的列表长度*/public <T> Long setList(String key, T value, long timeout, TimeUnit timeUnit) {Long count = redisTemplate.opsForList().rightPush(key, value);setExpire(key, timeout, timeUnit);return count;}/*** 将数据批量添加到 Redis 中的列表类型** @param key    Redis 键* @param values 存储的值集合* @param <T>    值的类型* @return 添加后的列表长度*/public <T> Long setListAll(String key, T... values) {return redisTemplate.opsForList().rightPushAll(key, values);}/*** 将数据批量添加到 Redis 中的列表类型,并设置过期时间** @param key       Redis 键* @param timeout   过期时间* @param timeUnit  时间单位* @param values    存储的值集合* @param <T>       值的类型* @return 添加后的列表长度*/public <T> Long setListAll(String key, long timeout, TimeUnit timeUnit, T... values) {Long count = redisTemplate.opsForList().rightPushAll(key, values);setExpire(key, timeout, timeUnit);return count;}/*** 获取 Redis 中列表类型数据的指定范围(索引)** @param key   Redis 键* @param start 起始索引* @param end   结束索引* @param <T>   值的类型* @return 指定范围内的列表数据*/public <T> List<T> getList(String key, long start, long end) {List<T> result = (List<T>) redisTemplate.opsForList().range(key, start, end);return result;}/*** 获取 Redis 中列表类型数据的指定索引值** @param key   Redis 键* @param index 索引值* @param <T>   值的类型* @return 列表中指定索引的数据*/public <T> T getListByIndex(String key, long index) {return (T) redisTemplate.opsForList().index(key, index);}/*** 获取 Redis 中列表类型的大小** @param key Redis 键* @return 列表长度*/public Long getListSize(String key) {return redisTemplate.opsForList().size(key);}/*** 删除 Redis 中列表类型的指定数据** @param key   Redis 键* @param count 删除的数量* @param value 要删除的值* @param <T>   值的类型* @return 删除的数量*/public <T> Long deleteList(String key, long count, T value) {return redisTemplate.opsForList().remove(key, count, value);}/*** 将数据添加到 Redis 中的集合类型** @param key    Redis 键* @param values 存储的值集合* @param <T>    值的类型* @return 添加的元素数量*/public <T> Long setSet(String key, T... values) {return redisTemplate.opsForSet().add(key, values);}/*** 将数据添加到 Redis 中的集合类型,并设置过期时间** @param key       Redis 键* @param timeout   过期时间* @param timeUnit  时间单位* @param values    存储的值集合* @param <T>       值的类型* @return 添加的元素数量*/public <T> Long setSet(String key, long timeout, TimeUnit timeUnit, T... values) {Long count = redisTemplate.opsForSet().add(key, values);setExpire(key, timeout, timeUnit);return count;}/*** 获取 Redis 中集合类型的数据** @param key Redis 键* @param <T> 值的类型* @return 集合数据*/public <T> Set<T> getSet(String key) {Set<T> result = (Set<T>) redisTemplate.opsForSet().members(key);return result;}/*** 删除 Redis 中集合类型的数据** @param key    Redis 键* @param values 要删除的值集合* @param <T>    值的类型* @return 删除的元素数量*/public <T> Long deleteSet(String key, T... values) {return redisTemplate.opsForSet().remove(key, values);}/*** 判断 Redis 中集合类型的数据是否包含指定的值** @param key   Redis 键* @param value 要检查的值* @param <T>   值的类型* @return 是否包含指定的值*/public <T> Boolean hasSetValue(String key, T value) {return redisTemplate.opsForSet().isMember(key, value);}/*** 获取 Redis 中集合类型数据的大小** @param key Redis 键* @return 集合长度*/public Long getSetSize(String key) {return redisTemplate.opsForSet().size(key);}/*** 对 Redis 中的有序集合进行递增操作** @param key   Redis 键* @param value 元素值* @param score 增加的分值* @param <T>   值的类型* @return 增加后的分值*/public <T> Double incrZet(String key, T value, Double score) {return redisTemplate.opsForZSet().incrementScore(key, value, score);}/*** 对 Redis 中的有序集合进行递减操作** @param key   Redis 键* @param value 元素值* @param score 减少的分值* @param <T>   值的类型* @return 减少后的分值*/public <T> Double decrZet(String key, T value, Double score) {return redisTemplate.opsForZSet().incrementScore(key, value, -score);}/*** 删除 Redis 中有序集合的数据** @param key    Redis 键* @param values 要删除的元素值* @param <T>    值的类型* @return 删除的元素数量*/public <T> Long deleteZetScore(String key, T... values) {return redisTemplate.opsForZSet().remove(key, values);}/*** 获取 Redis 中有序集合的指定范围内的数据(按分值倒序)** @param key   Redis 键* @param start 起始索引* @param end   结束索引* @return 元素及其分值的集合*/public Map<Object, Double> zReverseRangeWithScore(String key, long start, long end) {return redisTemplate.opsForZSet().reverseRangeWithScores(key, start, end).stream().collect(Collectors.toMap(ZSetOperations.TypedTuple::getValue, ZSetOperations.TypedTuple::getScore));}/*** 获取 Redis 中有序集合中指定元素的分值** @param key   Redis 键* @param value 元素值* @param <T>   值的类型* @return 分值*/public <T> Double getZsetScore(String key, T value) {return redisTemplate.opsForZSet().score(key, value);}/*** 获取 Redis 中有序集合所有元素及其分值** @param key Redis 键* @return 元素及其分值的集合*/public Map<Object, Double> getZsetAllScore(String key) {return Objects.requireNonNull(redisTemplate.opsForZSet().rangeWithScores(key, 0, -1)).stream().collect(Collectors.toMap(ZSetOperations.TypedTuple::getValue, ZSetOperations.TypedTuple::getScore));}
}

相关文章:

后端开发 Springboot整合Redis Spring Data Redis 模板

目录 redis 配置 RedisConfig 类 完整代码 代码讲解 1. 类定义和注解 2. 定义 RedisTemplate Bean 3. 配置 JSON 序列化 4. 配置 Redis 的 key 和 value 序列化方式 5. 完成配置并返回 RedisTemplate 总结 redis 服务接口实现类 类级别 注入 RedisTemplate 常用 Re…...

代码随想录算法训练营第 4 天(链表 2)| 24. 两两交换链表中的节点19.删除链表的倒数第N个节点 -

一、24. 两两交换链表中的节点 题目&#xff1a;24. 两两交换链表中的节点 - 力扣&#xff08;LeetCode&#xff09; 视频&#xff1a;帮你把链表细节学清楚&#xff01; | LeetCode&#xff1a;24. 两两交换链表中的节点_哔哩哔哩_bilibili 讲解&#xff1a;代码随想录 dummy-…...

【RDMA学习笔记】1:RDMA(Remote Direct Memory Access)介绍

从帝国理工的PPT学习。 什么是RDMA Remote Direct Memory Access&#xff0c;也就是Remote的DMA&#xff0c;是一种硬件机制&#xff0c;能直接访问远端结点的内存&#xff0c;而不需要处理器介入。 其中&#xff1a; Remote&#xff1a;跨node进行数据传输Direct&#xff…...

网络安全常见的35个安全框架及模型

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 01、概述 网络安全专业机构制定的一套标准、准则和程序&#xff0c;旨在帮助组织了解和管理面临的网络安全风险。优秀的安全框架及模型应该为用户提供一种可靠方法&#xff0c;帮助其实现网络安全建设…...

Elasticsearch介绍及使用

Elasticsearch 是一款基于 Lucene 库构建的开源、分布式、RESTful 风格的搜索引擎和分析引擎&#xff0c;具有强大的全文搜索、数据分析、机器学习等功能&#xff0c;广泛应用于日志分析、实时数据分析、全文检索等场景。 核心概念 索引&#xff08;Index&#xff09;&#xf…...

Leetocde516. 最长回文子序列 动态规划

原题链接&#xff1a;Leetocde516. 最长回文子序列 class Solution { public:int longestPalindromeSubseq(string s) {int n s.size();vector<vector<int>> dp(n, vector<int>(n, 1));for (int i 0; i < n; i) {dp[i][i] 1;if (i 1 < n &&…...

iOS 逆向学习 - Inter-Process Communication:进程间通信

iOS 逆向学习 - Inter-Process Communication&#xff1a;进程间通信 一、进程间通信概要二、iOS 进程间通信机制详解1. URL Schemes2. Pasteboard3. App Groups 和 Shared Containers4. XPC Services 三、不同进程间通信机制的差异四、总结 一、进程间通信概要 进程间通信&am…...

高级生化大纲

一&#xff0c;蛋白质化学&#xff1a; 蛋白质分离是生物化学和分子生物学研究中的一项基本技术&#xff0c;用于根据蛋白质的物理和化学特性将其从混合物中分离出来。 1. 离心分离法 离心分离法利用离心力来分离不同质量或密度的颗粒和分子。 差速离心&#xff1a;通过逐…...

YARN WebUI 服务

一、WebUI 使用 与HDFS一样&#xff0c;YARN也提供了一个WebUI服务&#xff0c;可以使用YARN Web用户界面监视群集、队列、应用程序、服务、流活动和节点信息。还可以查看集群详细配置的信息&#xff0c;检查各种应用程序和服务的日志。 1.1 首页 浏览器输入http://node2.itc…...

【Unity3D】利用IJob、Burst优化处理切割物体

参考文章&#xff1a; 【Unity】切割网格 【Unity3D】ECS入门学习&#xff08;一&#xff09;导入及基础学习_unity ecs教程-CSDN博客 【Unity3D】ECS入门学习&#xff08;十二&#xff09;IJob、IJobFor、IJobParallelFor_unity ijobparallelfor-CSDN博客 工程资源地址&…...

【大前端】Vue3 工程化项目使用详解

目录 一、前言 二、前置准备 2.1 环境准备 2.1.1 create-vue功能 2.1.2 nodejs环境 2.1.3 配置nodejs的环境变量 2.1.4 更换安装包的源 三、工程化项目创建与启动过程 3.1 创建工程化项目 3.2 项目初始化 3.3 项目启动 3.4 核心文件说明 四、VUE两种不同的API风格 …...

基于文件系统分布式锁原理

分布式锁&#xff1a;在一个公共的存储服务上打上一个标记&#xff0c;如Redis的setnx命令&#xff0c;是先到先得方式获得锁&#xff0c;ZooKeeper有点像下面的demo,比较大小的方式判决谁获得锁。 package com.ldj.mybatisflex.demo;import java.util.*; import java.util.co…...

简历整理YH

一&#xff0c;订单中心 1&#xff0c;调拨单 融通(Rocketmq)-订单中心&#xff1a;ECC_BMS123(已出单)&#xff0c;125(分配),127(发货),129(收货) 通过RocketMq接入多场景订单数据 2&#xff0c;销售单 sap&#xff08;FTP&#xff09;-订单中心&#xff0c;下发1002,1003,…...

Kotlin 协程基础三 —— 结构化并发(二)

Kotlin 协程基础系列&#xff1a; Kotlin 协程基础一 —— 总体知识概述 Kotlin 协程基础二 —— 结构化并发&#xff08;一&#xff09; Kotlin 协程基础三 —— 结构化并发&#xff08;二&#xff09; Kotlin 协程基础四 —— CoroutineScope 与 CoroutineContext Kotlin 协程…...

微信小程序实现长按录音,点击播放等功能,CSS实现语音录制动画效果

有一个需求需要在微信小程序上实现一个长按时进行语音录制&#xff0c;录制时间最大为60秒&#xff0c;录制完成后&#xff0c;可点击播放&#xff0c;播放时再次点击停止播放&#xff0c;可以反复录制&#xff0c;新录制的语音把之前的语音覆盖掉&#xff0c;也可以主动长按删…...

校园跑腿小程序---轮播图,导航栏开发

hello hello~ &#xff0c;这里是 code袁~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f981;作者简介&#xff1a;一名喜欢分享和记录学习的在校大学生…...

详细全面讲解C++中重载、隐藏、覆盖的区别

文章目录 总结1、重载示例代码特点1. 模板函数和非模板函数重载2. 重载示例与调用规则示例代码调用规则解释3. 特殊情况与注意事项二义性问题 函数特化与重载的交互 2. 函数隐藏&#xff08;Function Hiding&#xff09;概念示例代码特点 3. 函数覆盖&#xff08;重写&#xff…...

一文读懂单片机的串口

目录 串口通信的基本概念 串口通信的关键参数 单片机串口的硬件连接 单片机串口的工作原理 数据发送过程 数据接收过程 单片机串口的编程实现 以51单片机为例 硬件连接 初始化串口 发送数据 接收数据 串口中断服务函数 代码示例 单片机串口的应用实例 单片机与…...

HTML5 网站模板

HTML5 网站模板 参考 HTML5 Website Templates...

mybatis分页插件:PageHelper、mybatis-plus-jsqlparser(解决SQL_SERVER2005连接分页查询OFFSET问题)

文章目录 引言I PageHelper坐标II mybatis-plus-jsqlparser坐标Spring Boot 添加分页插件自定义 Mapper 方法中使用分页注意事项解决SQL_SERVER2005连接分页查询OFFSET问题知识扩展MyBatis-Plus 框架结构mybatis-plus-jsqlparser的 Page 类引言 PageHelper import com.github.p…...

基于FPGA的PID算法学习———实现PID比例控制算法

基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容&#xff1a;参考网站&#xff1a; PID算法控制 PID即&#xff1a;Proportional&#xff08;比例&#xff09;、Integral&#xff08;积分&…...

Day131 | 灵神 | 回溯算法 | 子集型 子集

Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 笔者写过很多次这道题了&#xff0c;不想写题解了&#xff0c;大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...

python/java环境配置

环境变量放一起 python&#xff1a; 1.首先下载Python Python下载地址&#xff1a;Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个&#xff0c;然后自定义&#xff0c;全选 可以把前4个选上 3.环境配置 1&#xff09;搜高级系统设置 2…...

2.Vue编写一个app

1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

Map相关知识

数据结构 二叉树 二叉树&#xff0c;顾名思义&#xff0c;每个节点最多有两个“叉”&#xff0c;也就是两个子节点&#xff0c;分别是左子 节点和右子节点。不过&#xff0c;二叉树并不要求每个节点都有两个子节点&#xff0c;有的节点只 有左子节点&#xff0c;有的节点只有…...

华硕a豆14 Air香氛版,美学与科技的馨香融合

在快节奏的现代生活中&#xff0c;我们渴望一个能激发创想、愉悦感官的工作与生活伙伴&#xff0c;它不仅是冰冷的科技工具&#xff0c;更能触动我们内心深处的细腻情感。正是在这样的期许下&#xff0c;华硕a豆14 Air香氛版翩然而至&#xff0c;它以一种前所未有的方式&#x…...

基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解

JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用&#xff0c;结合SQLite数据库实现联系人管理功能&#xff0c;并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能&#xff0c;同时可以最小化到系统…...

人机融合智能 | “人智交互”跨学科新领域

本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...

C#学习第29天:表达式树(Expression Trees)

目录 什么是表达式树&#xff1f; 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持&#xff1a; 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...

关于uniapp展示PDF的解决方案

在 UniApp 的 H5 环境中使用 pdf-vue3 组件可以实现完整的 PDF 预览功能。以下是详细实现步骤和注意事项&#xff1a; 一、安装依赖 安装 pdf-vue3 和 PDF.js 核心库&#xff1a; npm install pdf-vue3 pdfjs-dist二、基本使用示例 <template><view class"con…...