当前位置: 首页 > 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…...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…...

JavaSec-RCE

简介 RCE(Remote Code Execution)&#xff0c;可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景&#xff1a;Groovy代码注入 Groovy是一种基于JVM的动态语言&#xff0c;语法简洁&#xff0c;支持闭包、动态类型和Java互操作性&#xff0c…...

stm32G473的flash模式是单bank还是双bank?

今天突然有人stm32G473的flash模式是单bank还是双bank&#xff1f;由于时间太久&#xff0c;我真忘记了。搜搜发现&#xff0c;还真有人和我一样。见下面的链接&#xff1a;https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...

简易版抽奖活动的设计技术方案

1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...

在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能

下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能&#xff0c;包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...

MVC 数据库

MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

页面渲染流程与性能优化

页面渲染流程与性能优化详解&#xff08;完整版&#xff09; 一、现代浏览器渲染流程&#xff08;详细说明&#xff09; 1. 构建DOM树 浏览器接收到HTML文档后&#xff0c;会逐步解析并构建DOM&#xff08;Document Object Model&#xff09;树。具体过程如下&#xff1a; (…...

如何为服务器生成TLS证书

TLS&#xff08;Transport Layer Security&#xff09;证书是确保网络通信安全的重要手段&#xff0c;它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书&#xff0c;可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...

【AI学习】三、AI算法中的向量

在人工智能&#xff08;AI&#xff09;算法中&#xff0c;向量&#xff08;Vector&#xff09;是一种将现实世界中的数据&#xff08;如图像、文本、音频等&#xff09;转化为计算机可处理的数值型特征表示的工具。它是连接人类认知&#xff08;如语义、视觉特征&#xff09;与…...

Python如何给视频添加音频和字幕

在Python中&#xff0c;给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加&#xff0c;包括必要的代码示例和详细解释。 环境准备 在开始之前&#xff0c;需要安装以下Python库&#xff1a;…...