后端开发 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);
}
setObject和getObject分别用于设置和获取 Redis 中的字符串类型数据。incr和decr用于对字符串类型的值进行递增和递减操作。
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);
}
setHash和getHash用于设置和获取 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 返回。
其他方法
deleteObject和deleteList等方法用于删除 Redis 中的键值对、列表中的元素等。hasHashValue用于检查 Redis 哈希表中是否存在指定的值。deleteSet和deleteZetScore用于删除集合和有序集合中的元素。
总结
该 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. 两两交换链表中的节点 题目:24. 两两交换链表中的节点 - 力扣(LeetCode) 视频:帮你把链表细节学清楚! | LeetCode:24. 两两交换链表中的节点_哔哩哔哩_bilibili 讲解:代码随想录 dummy-…...
【RDMA学习笔记】1:RDMA(Remote Direct Memory Access)介绍
从帝国理工的PPT学习。 什么是RDMA Remote Direct Memory Access,也就是Remote的DMA,是一种硬件机制,能直接访问远端结点的内存,而不需要处理器介入。 其中: Remote:跨node进行数据传输Directÿ…...
网络安全常见的35个安全框架及模型
大家读完觉得有帮助记得关注和点赞!!! 01、概述 网络安全专业机构制定的一套标准、准则和程序,旨在帮助组织了解和管理面临的网络安全风险。优秀的安全框架及模型应该为用户提供一种可靠方法,帮助其实现网络安全建设…...
Elasticsearch介绍及使用
Elasticsearch 是一款基于 Lucene 库构建的开源、分布式、RESTful 风格的搜索引擎和分析引擎,具有强大的全文搜索、数据分析、机器学习等功能,广泛应用于日志分析、实时数据分析、全文检索等场景。 核心概念 索引(Index)…...
Leetocde516. 最长回文子序列 动态规划
原题链接: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:进程间通信 一、进程间通信概要二、iOS 进程间通信机制详解1. URL Schemes2. Pasteboard3. App Groups 和 Shared Containers4. XPC Services 三、不同进程间通信机制的差异四、总结 一、进程间通信概要 进程间通信&am…...
高级生化大纲
一,蛋白质化学: 蛋白质分离是生物化学和分子生物学研究中的一项基本技术,用于根据蛋白质的物理和化学特性将其从混合物中分离出来。 1. 离心分离法 离心分离法利用离心力来分离不同质量或密度的颗粒和分子。 差速离心:通过逐…...
YARN WebUI 服务
一、WebUI 使用 与HDFS一样,YARN也提供了一个WebUI服务,可以使用YARN Web用户界面监视群集、队列、应用程序、服务、流活动和节点信息。还可以查看集群详细配置的信息,检查各种应用程序和服务的日志。 1.1 首页 浏览器输入http://node2.itc…...
【Unity3D】利用IJob、Burst优化处理切割物体
参考文章: 【Unity】切割网格 【Unity3D】ECS入门学习(一)导入及基础学习_unity ecs教程-CSDN博客 【Unity3D】ECS入门学习(十二)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风格 …...
基于文件系统分布式锁原理
分布式锁:在一个公共的存储服务上打上一个标记,如Redis的setnx命令,是先到先得方式获得锁,ZooKeeper有点像下面的demo,比较大小的方式判决谁获得锁。 package com.ldj.mybatisflex.demo;import java.util.*; import java.util.co…...
简历整理YH
一,订单中心 1,调拨单 融通(Rocketmq)-订单中心:ECC_BMS123(已出单),125(分配),127(发货),129(收货) 通过RocketMq接入多场景订单数据 2,销售单 sap(FTP)-订单中心,下发1002,1003,…...
Kotlin 协程基础三 —— 结构化并发(二)
Kotlin 协程基础系列: Kotlin 协程基础一 —— 总体知识概述 Kotlin 协程基础二 —— 结构化并发(一) Kotlin 协程基础三 —— 结构化并发(二) Kotlin 协程基础四 —— CoroutineScope 与 CoroutineContext Kotlin 协程…...
微信小程序实现长按录音,点击播放等功能,CSS实现语音录制动画效果
有一个需求需要在微信小程序上实现一个长按时进行语音录制,录制时间最大为60秒,录制完成后,可点击播放,播放时再次点击停止播放,可以反复录制,新录制的语音把之前的语音覆盖掉,也可以主动长按删…...
校园跑腿小程序---轮播图,导航栏开发
hello hello~ ,这里是 code袁~💖💖 ,欢迎大家点赞🥳🥳关注💥💥收藏🌹🌹🌹 🦁作者简介:一名喜欢分享和记录学习的在校大学生…...
详细全面讲解C++中重载、隐藏、覆盖的区别
文章目录 总结1、重载示例代码特点1. 模板函数和非模板函数重载2. 重载示例与调用规则示例代码调用规则解释3. 特殊情况与注意事项二义性问题 函数特化与重载的交互 2. 函数隐藏(Function Hiding)概念示例代码特点 3. 函数覆盖(重写ÿ…...
一文读懂单片机的串口
目录 串口通信的基本概念 串口通信的关键参数 单片机串口的硬件连接 单片机串口的工作原理 数据发送过程 数据接收过程 单片机串口的编程实现 以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…...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...
国防科技大学计算机基础课程笔记02信息编码
1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制,因此这个了16进制的数据既可以翻译成为这个机器码,也可以翻译成为这个国标码,所以这个时候很容易会出现这个歧义的情况; 因此,我们的这个国…...
【kafka】Golang实现分布式Masscan任务调度系统
要求: 输出两个程序,一个命令行程序(命令行参数用flag)和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽,然后将消息推送到kafka里面。 服务端程序: 从kafka消费者接收…...
通过Wrangler CLI在worker中创建数据库和表
官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...
测试markdown--肇兴
day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
【Linux】Linux 系统默认的目录及作用说明
博主介绍:✌全网粉丝23W,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...
NPOI Excel用OLE对象的形式插入文件附件以及插入图片
static void Main(string[] args) {XlsWithObjData();Console.WriteLine("输出完成"); }static void XlsWithObjData() {// 创建工作簿和单元格,只有HSSFWorkbook,XSSFWorkbook不可以HSSFWorkbook workbook new HSSFWorkbook();HSSFSheet sheet (HSSFSheet)workboo…...
【大模型】RankRAG:基于大模型的上下文排序与检索增强生成的统一框架
文章目录 A 论文出处B 背景B.1 背景介绍B.2 问题提出B.3 创新点 C 模型结构C.1 指令微调阶段C.2 排名与生成的总和指令微调阶段C.3 RankRAG推理:检索-重排-生成 D 实验设计E 个人总结 A 论文出处 论文题目:RankRAG:Unifying Context Ranking…...
