Spring-data-redis是spring大家族的一部分,提供了在srping应用中通过简单的配置访问redis服务,对reids底层开发包(Jedis, JRedis, and RJC)进行了高度封装,RedisTemplate提供了redis各种操作、异常处理及序列化,支持发布订阅,并对spring 3.1 cache进行了实现。
springboot项目中一般不直接使用Jedis进行redis连接等操作了,因为集成了Spring-data-redis,所以一般直接使用Spring-data-redis即可,非常得方便。
在 springboot 1.5.x版本的默认的Redis客户端是 Jedis实现的,springboot 2.x版本中默认客户端是用 lettuce实现的。
Jedis 和 Lettuce 是 Java 操作 Redis 的客户端。在 Spring Boot 1.x 版本默认使用的是 jedis ,而在 Spring Boot 2.x 版本默认使用的就是Lettuce。关于 Jedis 跟 Lettuce 的区别如下:
1、Jedis在实现上是直接连接的redis server,如果在多线程环境下是非线程安全的,这个时候只有使用连接池,为每个Jedis实例增加物理连接
2、Lettuce的连接是基于Netty的,连接实例(StatefulRedisConnection)可以在多个线程间并发访问,应为StatefulRedisConnection是线程安全的,所以一个连接实例(StatefulRedisConnection)就可以满足多线程环境下的并发访问,当然这个也是可伸缩的设计,一个连接实例不够的情况也可以按需增加连接实例。
一、RedisTemplate 简单使用
1)引入依赖:
<!--redis相关的依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--spring2.0集成redis所需common-pool2-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
2) 配置文件:
1、单机连接
#Redis 配置,以下除了 timeout 外全部为默认配置.
spring:
redis:
port: 6379
# Redis服务器地址
host: localhost
# Redis数据库索引(默认为0)
database: 0
# Redis服务器连接密码(默认为空)
password: 123456
# 连接超时时间(毫秒)
timeout: 5000ms
# 连接池最大连接数(使用负值表示没有限制)
lettuce:
pool:
max-active: 1000 #池中可以分配的最大连接数,使用负值表示无限制。
max-idle: 500 #池中'空闲'连接的最大数量,使用负值表示空闲连接的数量不限。
min-idle: 500 #池中要维护的最小空闲连接数的目标,此设置仅在为正时有效。
max-wait: -1ms #池中连接耗尽时引发异常之前,等待连接分配的最长时间。使用负值可以无限期等待。
2、 哨兵模式
spring:
redis:
# Redis数据库索引(默认为0)
database: 0
# Redis服务器连接密码(默认为空)
password: password@1
# 连接超时时间(毫秒)
timeout: 5000ms
# 连接池最大连接数(使用负值表示没有限制)
sentinel:
master: master
nodes: 127.0.0.1:26379,127.0.0.1:26380,127.0.0.1:26381
lettuce:
pool:
max-active: 1000 #池中可以分配的最大连接数,使用负值表示无限制。
max-idle: 500 #池中'空闲'连接的最大数量,使用负值表示空闲连接的数量不限。
min-idle: 500 #池中要维护的最小空闲连接数的目标,此设置仅在为正时有效。
max-wait: -1ms #池中连接耗尽时引发异常之前,等待连接分配的最长时间。使用负值可以无限期等待。
3、集群模式
spring:
redis:
# Redis数据库索引(默认为0)
database: 0
# Redis服务器连接密码(默认为空)
password: 123456
# 连接超时时间(毫秒)
timeout: 5000ms
# 连接池最大连接数(使用负值表示没有限制)
cluster:
nodes: 192.168.131.118:4883,192.168.131.118:4884,192.168.131.118:4885
lettuce:
pool:
max-active: 1000 #池中可以分配的最大连接数,使用负值表示无限制。
max-idle: 500 #池中'空闲'连接的最大数量,使用负值表示空闲连接的数量不限。
min-idle: 500 #池中要维护的最小空闲连接数的目标,此设置仅在为正时有效。
max-wait: -1ms #池中连接耗尽时引发异常之前,等待连接分配的最长时间。使用负值可以无限期等待。
3) 简单调用
实际上引入依赖 以及 添加好配置文件之后就可以进行api调用了,调用方式很简单只需要使用@Autowired注解将RedisTemplate进行注入即可:
@Autowired
private RedisTemplate redisTemplate;
@GetMapping("/aaa")
public boolean test() {
redisTemplate.opsForValue().set("name", "123456");
return true;
}
简单写个接口demo,上面的语句就是设置一个key为name,value为123456得数据。这样就可以了。但是虽然存储成功了,去redis中查看发现,存储是这样的:
左边得是key,右边得是value,会发现存储得类型是一串很奇怪得数据。
这是因为redis序列化方式得问题,需要简单说一下redisTemplate的序列化机制。
二、RedisTemplate序列化方式
1)RedisTemplate源码:
序列化需要注意的是这四个属性:
keySerializer
:1、用途:这个属性定义了 RedisTemplate 如何序列化和反序列化 Redis 键(key)的数据类型。
2、默认值:默认为
null
,如果不设置,会使用 RedisTemplate 的默认键序列化器。
valueSerializer
:1、用途:这个属性定义了 RedisTemplate 如何序列化和反序列化 Redis 值(value)的数据类型。
2、默认值:默认为
null
,如果不设置,会使用 RedisTemplate 的默认值序列化器。
hashKeySerializer
:1、用途:这个属性定义了 RedisTemplate 如何序列化和反序列化 Redis 哈希的键的数据类型(在使用 Hash 类型时)。
2、默认值:默认为
null
,如果不设置,会使用 RedisTemplate 的默认哈希键序列化器。
hashValueSerializer
:1、用途:这个属性定义了 RedisTemplate 如何序列化和反序列化 Redis 哈希的值的数据类型(在使用 Hash 类型时)
2、默认值:默认为
null
,如果不设置,会使用 RedisTemplate 的默认哈希值序列化器。
这四个属性就是redis在存取数据时对应的序列化的方式。会发现这个四个属性都是RedisSerializer类型的,所以如果要设置对应的序列化属性,我们就需要使用RedisSerializer对应的实现类即可。
2)RedisSerializer 接口的实现类
RedisSerializer 接口的实现类 有如下几种:
也就是说我们要设置序列化方式,使用上面的实现类进行实现即可。
归类一下可以分为:
- JDK 序列化方式 (默认)
- String 序列化方式
- SON 序列化方式
- XML 序列化方式
3)序列化方式 :
1.JDK 序列化方式 (默认)
org.springframework.data.redis.serializer.JdkSerializationRedisSerializer
,默认情况下,RedisTemplate 使用该数据列化方式。
Spring Boot 自动化配置 RedisTemplate Bean 对象时,就未设置默认的序列化方式。绝大多数情况下,不推荐使用 JdkSerializationRedisSerializer 进行序列化。主要是不方便人工排查数据。上面的demo种就是这样,我们会发现KEY 前面带着奇怪的 16 进制字符 , VALUE 也是一串奇怪的 16 进制字符。所以序列化成这样非常不方便我们进行排查。
2)String 序列化方式
org.springframework.data.redis.serializer.StringRedisSerializer
,字符串和二进制数组的直接转换
一般我们key值都是使用 String 类型得序列化方式。
3)JSON 序列化方式
org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer
使用 Jackson 实现 JSON 的序列化方式,并且从 Generic 单词可以看出,是支持所有类。
这里需要简单得讲解一下,先看一下使用这个类序列化后得结果:
标准得json格式:
{
"id": 100,
"name": "小工匠",
"sex": "Male"
}
使用GenericJackson2JsonRedisSerializer 后得序列化格式:
{
"@class": "com.artisan.domain.Artisan",
"id": 100,
"name": "小工匠",
"sex": "Male"
}
会发现同一个对象,序列化后的内容不太一样,其实可以简单理解为,GenericJackson2JsonRedisSerializer
在序列化对象时,会将对象的对应的全类名也存储下来,这样在反序列化时,就可以直接通过全类名,直接反序列化为对应的对象类型。
4.XML 序列化方式
org.springframework.data.redis.serializer.OxmSerializer
使用 Spring OXM 实现将对象和 String 的转换,从而 String 和二进制数组的转换。 没见过哪个项目用过,不啰嗦了
https://www.cnblogs.com/csjoz/p/16337145.html
4) json序列化额外配置:
我们在配置redis的value值为json序列化时,如下所示:
@Bean
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
// 创建redisTemplate对象
RedisTemplate<Object, Object> template = new RedisTemplate<>();
// 连接工厂
template.setConnectionFactory(redisConnectionFactory);
// 获取序列化工具
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
Jackson2JsonRedisSerializer jsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
// 设置key的序列化 (Redis 默认序列化工具)
template.setKeySerializer(stringRedisSerializer);
template.setHashKeySerializer(stringRedisSerializer);
// 设置value的序列化 (Jackson 序列化工具)
template.setValueSerializer(jsonRedisSerializer);
template.setHashValueSerializer(jsonRedisSerializer);
// 开启事务
template.setEnableTransactionSupport(true);
return template;
}
上述配置就可以满足基本需求,但当java实体类含有LocalDateTime数据类型时会报错:org.springframework.data.redis.serializer.SerializationException: Could not write JSON: Java 8 date/time type `java.time.LocalDateTime` not supported by default: add Module
所以我们要定义一些自定义配置这样就能解决日期类的序列化的问题,还有一些别的序列化配置,可以选择使用。
@Bean
@Resource
public RedisTemplate<String, Object> redisTemplate(@Lazy RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
// 设置key的序列化方式,采用StringRedisSerializer
GenericToStringSerializer<String> keySerializer = new GenericToStringSerializer<>(String.class);
redisTemplate.setKeySerializer(keySerializer);
redisTemplate.setHashKeySerializer(keySerializer);
// 设置value的序列化方式,采用Jackson2JsonRedisSerializer
redisTemplate.setValueSerializer(valueSerializer());
redisTemplate.setHashValueSerializer(valueSerializer());
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
// key键序列化方式
private RedisSerializer<String> keySerializer() {
return new StringRedisSerializer();
}
// value值序列化方式
private GenericJackson2JsonRedisSerializer valueSerializer(){
ObjectMapper objectMapper = new ObjectMapper();
// 反序列化时候遇到不匹配的属性并不抛出异常
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
// 序列化时候遇到空对象不抛出异常
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
// 反序列化的时候如果是无效子类型,不抛出异常
objectMapper.configure(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE, false);
// 不使用默认的dateTime进行序列化,
objectMapper.configure(SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS, false);
// 使用JSR310提供的序列化类,里面包含了大量的JDK8时间序列化类
objectMapper.registerModule(new JavaTimeModule());
// 启用反序列化所需的类型信息,在属性中添加@class
objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL,
JsonTypeInfo.As.PROPERTY);
// 配置null值的序列化器
GenericJackson2JsonRedisSerializer.registerNullValueSerializer(objectMapper, null);
return new GenericJackson2JsonRedisSerializer(objectMapper);
}
使用GenericJackson2JsonRedisSerializer的时候会有一些坑,可以自行查阅一下,正常业务大部分场景没有问题。还要注意需要用这个的小伙伴们注意一下,如果你涉及的项目是集群,考虑一下开启事务那行代码,会和springBoot的事务起冲突,这个也要注意一下。
GenericJackson2JsonRedisSerializer问题 & Jackson2JsonRedisSerializer & StringRedisSerializer-CSDN博客
三、redisTemplate 常用操作
1)operation接口
“RedisTemplate”类将同一类型操作封装为operation接口:
- ValueOperations:简单K-V操作
- SetOperations:set类型数据操作
- ZSetOperations:zset类型数据操作
- HashOperations:针对map类型的数据操作
- ListOperations:针对list类型的数据操作
2)BoundKeyOperations接口:
提供了对key的“bound”(绑定)便捷化操作API,可以通过bound封装指定的key,然后进行一系列的操作而无须“显式”的再次指定Key,即BoundKeyOperations:
- BoundValueOperations
- BoundSetOperations
- BoundListOperations
- BoundSetOperations
- BoundHashOperations
简单说一下这两个api的区别,第一类是所有key都可以直接操作的,第二类其实就是方便绑定一个key,然后一直对这一个key进行操作,避免反复指定key。
3)RedisTemplate的直接方法
1、删除单个key
//删除key
public void delete(String key){
redisTemplate.delete(key);
}
2、删除多个key
//删除多个key
public void deleteKey (String ...keys){
redisTemplate.delete(keys);
}
3、指定key的失效时间
//指定key的失效时间
public void expire(String key,long time){
redisTemplate.expire(key,time,TimeUnit.MINUTES);
}
4、根据key获取过期时间
//根据key获取过期时间
public long getExpire(String key){
Long expire = redisTemplate.getExpire(key);
return expire;
}
5、判断key是否存在
//判断key是否存在
public boolean hasKey(String key){
return redisTemplate.hasKey(key);
}
4)、String类型相关操作
//1、通过redisTemplate设置值
redisTemplate.boundValueOps("StringKey").set("StringValue");
redisTemplate.boundValueOps("StringKey").set("StringValue",1, TimeUnit.MINUTES);
//2、通过BoundValueOperations设置值
BoundValueOperations stringKey = redisTemplate.boundValueOps("StringKey");
stringKey.set("StringVaule");
stringKey.set("StringValue",1, TimeUnit.MINUTES);
//3、通过ValueOperations设置值
ValueOperations ops = redisTemplate.opsForValue();
ops.set("StringKey", "StringVaule");
ops.set("StringValue","StringVaule",1, TimeUnit.MINUTES);
redisTemplate.boundValueOps("StringKey").expire(1,TimeUnit.MINUTES);
redisTemplate.expire("StringKey",1,TimeUnit.MINUTES);
3)、获取缓存值(2/3是1的递进值)
//1、通过redisTemplate设置值
String str1 = (String) redisTemplate.boundValueOps("StringKey").get();
//2、通过BoundValueOperations获取值
BoundValueOperations stringKey = redisTemplate.boundValueOps("StringKey");
String str2 = (String) stringKey.get();
//3、通过ValueOperations获取值
ValueOperations ops = redisTemplate.opsForValue();
String str3 = (String) ops.get("StringKey");
Boolean result = redisTemplate.delete("StringKey");
5)、顺序递增
redisTemplate.boundValueOps("StringKey").increment(3L);
6)、顺序递减
redisTemplate.boundValueOps("StringKey").increment(-3L);
5)、Hash类型相关操作
//1、通过redisTemplate设置值
redisTemplate.boundHashOps("HashKey").put("SmallKey", "HashVaue");
//2、通过BoundValueOperations设置值
BoundHashOperations hashKey = redisTemplate.boundHashOps("HashKey");
hashKey.put("SmallKey", "HashVaue");
//3、通过ValueOperations设置值
HashOperations hashOps = redisTemplate.opsForHash();
hashOps.put("HashKey", "SmallKey", "HashVaue");
redisTemplate.boundValueOps("HashKey").expire(1,TimeUnit.MINUTES);
redisTemplate.expire("HashKey",1,TimeUnit.MINUTES);
HashMap<String, String> hashMap = new HashMap<>();
redisTemplate.boundHashOps("HashKey").putAll(hashMap );
4)、设置过期时间(单独设置)
redisTemplate.boundValueOps("HashKey").expire(1,TimeUnit.MINUTES);
redisTemplate.expire("HashKey",1,TimeUnit.MINUTES);
5)、提取所有的小key
//1、通过redisTemplate获取值
Set keys1 = redisTemplate.boundHashOps("HashKey").keys();
//2、通过BoundValueOperations获取值
BoundHashOperations hashKey = redisTemplate.boundHashOps("HashKey");
Set keys2 = hashKey.keys();
//3、通过ValueOperations获取值
HashOperations hashOps = redisTemplate.opsForHash();
Set keys3 = hashOps.keys("HashKey");
//1、通过redisTemplate获取值
List values1 = redisTemplate.boundHashOps("HashKey").values();
//2、通过BoundValueOperations获取值
BoundHashOperations hashKey = redisTemplate.boundHashOps("HashKey");
List values2 = hashKey.values();
//3、通过ValueOperations获取值
HashOperations hashOps = redisTemplate.opsForHash();
List values3 = hashOps.values("HashKey");
//1、通过redisTemplate获取
String value1 = (String) redisTemplate.boundHashOps("HashKey").get("SmallKey");
//2、通过BoundValueOperations获取值
BoundHashOperations hashKey = redisTemplate.boundHashOps("HashKey");
String value2 = (String) hashKey.get("SmallKey");
//3、通过ValueOperations获取值
HashOperations hashOps = redisTemplate.opsForHash();
String value3 = (String) hashOps.get("HashKey", "SmallKey");
//1、通过redisTemplate获取
Map entries = redisTemplate.boundHashOps("HashKey").entries();
//2、通过BoundValueOperations获取值
BoundHashOperations hashKey = redisTemplate.boundHashOps("HashKey");
Map entries1 = hashKey.entries();
//3、通过ValueOperations获取值
HashOperations hashOps = redisTemplate.opsForHash();
Map entries2 = hashOps.entries("HashKey");
//删除小key
redisTemplate.boundHashOps("HashKey").delete("SmallKey");
//删除大key
redisTemplate.delete("HashKey");
Boolean isEmpty = redisTemplate.boundHashOps("HashKey").hasKey("SmallKey");
6)、Set类型相关操作
//1、通过redisTemplate设置值
redisTemplate.boundSetOps("setKey").add("setValue1", "setValue2", "setValue3");
//2、通过BoundValueOperations设置值
BoundSetOperations setKey = redisTemplate.boundSetOps("setKey");
setKey.add("setValue1", "setValue2", "setValue3");
//3、通过ValueOperations设置值
SetOperations setOps = redisTemplate.opsForSet();
setOps.add("setKey", "SetValue1", "setValue2", "setValue3");
redisTemplate.boundValueOps("setKey").expire(1,TimeUnit.MINUTES);
redisTemplate.expire("setKey",1,TimeUnit.MINUTES);
//1、通过redisTemplate获取值
Set set1 = redisTemplate.boundSetOps("setKey").members();
//2、通过BoundValueOperations获取值
BoundSetOperations setKey = redisTemplate.boundSetOps("setKey");
Set set2 = setKey.members();
//3、通过ValueOperations获取值
SetOperations setOps = redisTemplate.opsForSet();
Set set3 = setOps.members("setKey");
Boolean isEmpty = redisTemplate.boundSetOps("setKey").isMember("setValue2");
5)、获取Set缓存的长度
Long size = redisTemplate.boundSetOps("setKey").size();
6)、移除指定的元素
Long result1 = redisTemplate.boundSetOps("setKey").remove("setValue1");
7)、移除指定的key
Boolean result2 = redisTemplate.delete("setKey");
7)、 LIST类型相关操作
//1、通过redisTemplate设置值
redisTemplate.boundListOps("listKey").leftPush("listLeftValue1");
redisTemplate.boundListOps("listKey").rightPush("listRightValue2");
//2、通过BoundValueOperations设置值
BoundListOperations listKey = redisTemplate.boundListOps("listKey");
listKey.leftPush("listLeftValue3");
listKey.rightPush("listRightValue4");
//3、通过ValueOperations设置值
ListOperations opsList = redisTemplate.opsForList();
opsList.leftPush("listKey", "listLeftValue5");
opsList.rightPush("listKey", "listRightValue6");
ArrayList<String> list = new ArrayList<>();
redisTemplate.boundListOps("listKey").rightPushAll(list);
redisTemplate.boundListOps("listKey").leftPushAll(list);
3)、设置过期时间(单独设置)
redisTemplate.boundValueOps("listKey").expire(1,TimeUnit.MINUTES);
redisTemplate.expire("listKey",1,TimeUnit.MINUTES);
4)、获取List缓存全部内容(起始索引,结束索引)
List listKey1 = redisTemplate.boundListOps("listKey").range(0, 10);
5)、从左或从右弹出一个元素
//从左侧弹出一个元素
String listKey2 = (String) redisTemplate.boundListOps("listKey").leftPop();
//从右侧弹出一个元素
String listKey3 = (String) redisTemplate.boundListOps("listKey").rightPop();
6)、根据索引查询元素
String listKey4 = (String) redisTemplate.boundListOps("listKey").index(1);
7)、获取List缓存的长度
Long size = redisTemplate.boundListOps("listKey").size();
8)、根据索引修改List中的某条数据(key,索引,值)
redisTemplate.boundListOps("listKey").set(3L,"listLeftValue3");
9)、移除N个值为value(key,移除个数,值)
redisTemplate.boundListOps("listKey").remove(3L,"value");
8)、Zset类型的相关操作
//1、通过redisTemplate设置值
redisTemplate.boundZSetOps("zSetKey").add("zSetVaule", 100D);
//2、通过BoundValueOperations设置值
BoundZSetOperations zSetKey = redisTemplate.boundZSetOps("zSetKey");
zSetKey.add("zSetVaule", 100D);
//3、通过ValueOperations设置值
ZSetOperations zSetOps = redisTemplate.opsForZSet();
zSetOps.add("zSetKey", "zSetVaule", 100D);
DefaultTypedTuple<String> p1 = new DefaultTypedTuple<>("zSetVaule1", 2.1D);
DefaultTypedTuple<String> p2 = new DefaultTypedTuple<>("zSetVaule2", 3.3D);
redisTemplate.boundZSetOps("zSetKey").add(new HashSet<>(Arrays.asList(p1,p2)));
3)、按照排名先后(从小到大)打印指定区间内的元素, -1为打印全部
Set<String> range = redisTemplate.boundZSetOps("zSetKey").range(key, 0, -1);
4)、获得指定元素的分数
Double score = redisTemplate.boundZSetOps("zSetKey").score("zSetVaule");
5)、返回集合内的成员个数
Long size = redisTemplate.boundZSetOps("zSetKey").size();
6)、返回集合内指定分数范围的成员个数(Double类型)
Long COUNT = redisTemplate.boundZSetOps("zSetKey").count(0D, 2.2D);
7)、返回集合内元素在指定分数范围内的排名(从小到大)
Set byScore = redisTemplate.boundZSetOps("zSetKey").rangeByScore(0D, 2.2D);
8)、带偏移量和个数,(key,起始分数,最大分数,偏移量,个数)
Set<String> ranking2 = redisTemplate.opsForZSet().rangeByScore("zSetKey", 0D, 2.2D 1, 3);
9)、返回集合内元素的排名,以及分数(从小到大)
Set<TypedTuple<String>> tuples = redisTemplate.boundZSetOps("zSetKey").rangeWithScores(0L, 3L);
for (TypedTuple<String> tuple : tuples) {
System.out.println(tuple.getValue() + " : " + tuple.getScore());
}ss
10)、返回指定成员的排名
//从小到大
Long startRank = redisTemplate.boundZSetOps("zSetKey").rank("zSetVaule");
//从大到小
Long endRank = redisTemplate.boundZSetOps("zSetKey").reverseRank("zSetVaule");
11)、从集合中删除指定元素
redisTemplate.boundZSetOps("zSetKey").remove("zSetVaule");
12)、删除指定索引范围的元素(Long类型)
redisTemplate.boundZSetOps("zSetKey").removeRange(0L,3L);
13)、删除指定分数范围内的元素(Double类型)
redisTemplate.boundZSetOps("zSetKey").removeRangeByScorssse(0D,2.2D);
14)、为指定元素加分(Double类型)
Double score = redisTemplate.boundZSetOps("zSetKey").incrementScore("zSetVaule",1.1D);
springboot整合Redis中连接池jedis与lettuce的对比和实现_lettuce和jedis-CSDN博客
springboot2.0 集成redis服务详解,以及 (Lettuce & Jedis)_spring.redis.lettuce.pool.max-wait-CSDN博客
RedisTemplate 概述 与 操作 Redis 5 种数据类型、事务-CSDN博客
四、redisTemplate常用封装类:
1)封装类1:
package com.govd.utils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@Component
public class RedisUtil {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
/**
* 指定缓存失效时间
*
* @param key 键
* @param time 时间(秒)
*/
public boolean expire(String key, long time, TimeUnit timeUnit) {
try {
if (time > 0) {
redisTemplate.expire(key, time, timeUnit);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 根据key 获取过期时间
*
* @param key 键 不能为null
* @return 时间(秒) 返回0代表为永久有效
*/
public long getExpire(String key) {
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
}
/**
* 判断key是否存在
*
* @param key 键
* @return true 存在 false不存在
*/
public boolean hasKey(String key) {
try {
return redisTemplate.hasKey(key);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 删除缓存
*
* @param key 可以传一个值 或多个
*/
@SuppressWarnings("unchecked")
public void del(String... key) {
if (key != null && key.length > 0) {
if (key.length == 1) {
redisTemplate.delete(key[0]);
} else {
redisTemplate.delete((Collection<String>) CollectionUtils.arrayToList(key));
}
}
}
// ============================String=============================
/**
* 普通缓存获取
*
* @param key 键
* @return 值
*/
public Object get(String key) {
return key == null ? null : redisTemplate.opsForValue().get(key);
}
/**
* 普通缓存放入
*
* @param key 键
* @param value 值
* @return true成功 false失败
*/
public boolean set(String key, Object value) {
try {
redisTemplate.opsForValue().set(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 普通缓存放入并设置时间
*
* @param key 键
* @param value 值
* @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期
* @return true成功 false 失败
*/
public boolean set(String key, Object value, long time) {
try {
if (time > 0) {
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
} else {
set(key, value);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 递增
*
* @param key 键
* @param delta 要增加几(大于0)
*/
public long incr(String key, long delta) {
if (delta < 0) {
throw new RuntimeException("递增因子必须大于0");
}
return redisTemplate.opsForValue().increment(key, delta);
}
/**
* 递减
*
* @param key 键
* @param delta 要减少几(小于0)
*/
public long decr(String key, long delta) {
if (delta < 0) {
throw new RuntimeException("递减因子必须大于0");
}
return redisTemplate.opsForValue().increment(key, -delta);
}
// ================================Map=================================
/**
* HashGet
*
* @param key 键 不能为null
* @param item 项 不能为null
*/
public Object hget(String key, String item) {
return redisTemplate.opsForHash().get(key, item);
}
/**
* 获取hashKey对应的所有键值
*
* @param key 键
* @return 对应的多个键值
*/
public Map<Object, Object> hmget(String key) {
return redisTemplate.opsForHash().entries(key);
}
/**
* HashSet
*
* @param key 键
* @param map 对应多个键值
*/
public boolean hmset(String key, Map<String, Object> map) {
try {
redisTemplate.opsForHash().putAll(key, map);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* HashSet 并设置时间
*
* @param key 键
* @param map 对应多个键值
* @param time 时间(秒)
* @return true成功 false失败
*/
public boolean hmset(String key, Map<String, Object> map, long time, TimeUnit timeUnit) {
try {
redisTemplate.opsForHash().putAll(key, map);
if (time > 0) {
expire(key, time, timeUnit);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 向一张hash表中放入数据,如果不存在将创建
*
* @param key 键
* @param item 项
* @param value 值
* @return true 成功 false失败
*/
public boolean hset(String key, String item, Object value) {
try {
redisTemplate.opsForHash().put(key, item, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 向一张hash表中放入数据,如果不存在将创建
*
* @param key 键
* @param item 项
* @param value 值
* @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
* @return true 成功 false失败
*/
public boolean hset(String key, String item, Object value, long time, TimeUnit timeUnit) {
try {
redisTemplate.opsForHash().put(key, item, value);
if (time > 0) {
expire(key, time, timeUnit);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 删除hash表中的值
*
* @param key 键 不能为null
* @param item 项 可以使多个 不能为null
*/
public void hdel(String key, Object... item) {
redisTemplate.opsForHash().delete(key, item);
}
/**
* 判断hash表中是否有该项的值
*
* @param key 键 不能为null
* @param item 项 不能为null
* @return true 存在 false不存在
*/
public boolean hHasKey(String key, String item) {
return redisTemplate.opsForHash().hasKey(key, item);
}
/**
* hash递增 如果不存在,就会创建一个 并把新增后的值返回
*
* @param key 键
* @param item 项
* @param by 要增加几(大于0)
*/
public double hincr(String key, String item, double by) {
return redisTemplate.opsForHash().increment(key, item, by);
}
/**
* hash递减
*
* @param key 键
* @param item 项
* @param by 要减少记(小于0)
*/
public double hdecr(String key, String item, double by) {
return redisTemplate.opsForHash().increment(key, item, -by);
}
// ============================set=============================
/**
* 根据key获取Set中的所有值
*
* @param key 键
*/
public Set<Object> sGet(String key) {
try {
return redisTemplate.opsForSet().members(key);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 根据value从一个set中查询,是否存在
*
* @param key 键
* @param value 值
* @return true 存在 false不存在
*/
public boolean sHasKey(String key, Object value) {
try {
return redisTemplate.opsForSet().isMember(key, value);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 将数据放入set缓存
*
* @param key 键
* @param values 值 可以是多个
* @return 成功个数
*/
public long sSet(String key, Object... values) {
try {
return redisTemplate.opsForSet().add(key, values);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* 将set数据放入缓存
*
* @param key 键
* @param time 时间(秒)
* @param values 值 可以是多个
* @return 成功个数
*/
public long sSetAndTime(String key, long time, TimeUnit timeUnit, Object... values) {
try {
Long count = redisTemplate.opsForSet().add(key, values);
if (time > 0) {
expire(key, time, timeUnit);
}
return count;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* 获取set缓存的长度
*
* @param key 键
*/
public long sGetSetSize(String key) {
try {
return redisTemplate.opsForSet().size(key);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* 移除值为value的
*
* @param key 键
* @param values 值 可以是多个
* @return 移除的个数
*/
public long setRemove(String key, Object... values) {
try {
Long count = redisTemplate.opsForSet().remove(key, values);
return count;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
// ===============================list=================================
/**
* 获取list缓存的内容
*
* @param key 键
* @param start 开始
* @param end 结束 0 到 -1代表所有值
*/
public List<Object> lGet(String key, long start, long end) {
try {
return redisTemplate.opsForList().range(key, start, end);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 获取list缓存的长度
*
* @param key 键
*/
public long lGetListSize(String key) {
try {
return redisTemplate.opsForList().size(key);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* 通过索引 获取list中的值
*
* @param key 键
* @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推
*/
public Object lGetIndex(String key, long index) {
try {
return redisTemplate.opsForList().index(key, index);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 将list放入缓存
*
* @param key 键
* @param value 值
*/
public boolean lSet(String key, Object value) {
try {
redisTemplate.opsForList().rightPush(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 将list放入缓存
*
* @param key 键
* @param value 值
* @param time 时间(秒)
*/
public boolean lSet(String key, Object value, long time,TimeUnit timeUnit) {
try {
redisTemplate.opsForList().rightPush(key, value);
if (time > 0) {
expire(key, time,timeUnit);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 将list放入缓存
*
* @param key 键
* @param value 值
* @return
*/
public boolean lSet(String key, List<Object> value) {
try {
redisTemplate.opsForList().rightPushAll(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 将list放入缓存
*
* @param key 键
* @param value 值
* @param time 时间(秒)
* @return
*/
public boolean lSet(String key, List<Object> value, long time,TimeUnit timeUnit) {
try {
redisTemplate.opsForList().rightPushAll(key, value);
if (time > 0) {
expire(key, time,timeUnit);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 根据索引修改list中的某条数据
*
* @param key 键
* @param index 索引
* @param value 值
* @return
*/
public boolean lUpdateIndex(String key, long index, Object value) {
try {
redisTemplate.opsForList().set(key, index, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 移除N个值为value
*
* @param key 键
* @param count 移除多少个
* @param value 值
* @return 移除的个数
*/
public long lRemove(String key, long count, Object value) {
try {
Long remove = redisTemplate.opsForList().remove(key, count, value);
return remove;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
public long pfadd(String key, String value) {
return redisTemplate.opsForHyperLogLog().add(key, value);
}
public long pfcount(String key) {
return redisTemplate.opsForHyperLogLog().size(key);
}
public void pfremove(String key) {
redisTemplate.opsForHyperLogLog().delete(key);
}
public void pfmerge(String key1, String key2) {
redisTemplate.opsForHyperLogLog().union(key1, key2);
}
}
2)封装类2:
import org.springframework.data.redis.core.RedisTemplate;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function;
/**
* @description: 封装redis的常用操作
* @author: evildoer
* @datetime: 2021/4/1 12:54
*/
public class RedisUtils<K, V> {
/**
* redis最大存储数量
*/
private Integer size = 1000;
private final K KEY;
private final RedisTemplate<K, V> redisTemplate;
public RedisUtils(K key, RedisTemplate<K, V> redisTemplate) {
this.KEY = key;
this.redisTemplate = redisTemplate;
}
public RedisUtils(K key, RedisTemplate<K, V> redisTemplate, Integer size) {
this.KEY = key;
this.size = size;
this.redisTemplate = redisTemplate;
}
/**
* @description: 以hash的形式添加一条数据到redis
* @return: boolean
* @author: evildoer
* @datetime: 2021/4/1 12:58
*/
public boolean saveOrUpdateToRedis(V data, Function<V, ?> function) {
// 从缓存取数据列表
Map<Object, Object> map = redisTemplate.opsForHash().entries(KEY);
// 超出redis最大存储数量, 直接清空
if (map.size() > size) {
map.clear();
}
map.put(function.apply(data), data);
// 更新redis
redisTemplate.opsForHash().putAll(KEY, map);
return true;
}
/**
* @description: 以hash的形式添加一个集合的数据到redis
* @return: boolean
* @author: evildoer
* @datetime: 2021/4/1 12:58
*/
public boolean saveOrUpdateCollectionToRedis(Collection<V> collection, Function<V, ?> function) {
// 从缓存取数据列表
Map<Object, Object> map = redisTemplate.opsForHash().entries(KEY);
if(map.size() + collection.size() >= this.size){
map.clear();
}
// 更新redis
redisTemplate.opsForHash().putAll(KEY, map);
collection.forEach(data -> {
map.put(function.apply(data), data);
});
// 更新redis
redisTemplate.opsForHash().putAll(KEY, map);
return true;
}
/**
* @description: 通过Map的key从redis获取一条数据
* @author: evildoer
* @datetime: 2021/4/1 12:58
*/
public V fetchData(Object key) {
// 从缓存取数据
Map<Object, Object> map = redisTemplate.opsForHash().entries(KEY);
Object data = map.get(key);
if (null != data) {
return (V) data;
}
return null;
}
/**
* @description: 通过key从Map形式储存的redis删除一条数据, 返回删除的数据
* @author: evildoer
* @datetime: 2021/4/1 12:58
*/
public V delete(Object key) {
// 从缓存删除数据
Map<Object, Object> map = redisTemplate.opsForHash().entries(KEY);
Object data = map.get(key);
if (null != data) {
Object object = map.remove(key);
// 更新redis
redisTemplate.opsForHash().putAll(KEY, map);
return (V) object;
}
return null;
}
/**
* @description: 通过key从Map形式储存的redis删除多条数据
* @author: evildoer
* @datetime: 2021/4/1 12:58
*/
public boolean deleteBatch(Collection<V> collection, Function<V, ?> function) {
AtomicBoolean result = new AtomicBoolean(false);
// 从缓存删除数据
Map<Object, Object> map = redisTemplate.opsForHash().entries(KEY);
collection.forEach(data -> {
Object key = function.apply(data);
Object obj = map.get(key);
if (null != obj) {
result.set(true);
map.remove(key);
}
});
// 更新redis
if (result.get()) {
redisTemplate.opsForHash().putAll(KEY, map);
}
return result.get();
}
/**
* @description: 以List的形式添加一个数据到redis
* @author: evildoer
* @datetime: 2021/4/1 12:49
*/
public <D> boolean saveOrUpdateDataToRedis(D data, Function<D, ?> function) {
// 从缓存取数据列表
V v = redisTemplate.opsForList().leftPop(KEY);
List<D> list = null;
if (null == v) {
list = new LinkedList<>();
} else {
list = (List<D>) v;
}
// 是否要加入redis
boolean flag = true;
for (int i = 0; i < list.size(); i++) {
// 判断key是否相等
if (function.apply(data).equals(function.apply(list.get(i)))) {
// 查找到了, 修改flag为false, 更新redis
flag = false;
list.set(i, data);
}
}
if (flag) {
// 加入redis
list.add(data);
}
// 检查redis数据量, 超出预设值直接清理一半数据
if (list.size() >= size) {
list.subList(size / 2, list.size());
this.clear();
}
// 更新redis
redisTemplate.opsForList().leftPush(KEY, (V) list);
return true;
}
/**
* @description: 以List的形式添加一个集合的数据到redis
* @author: evildoer
* @datetime: 2021/4/1 12:49
*/
public <D> boolean saveOrUpdateDataCollectionToRedis(Collection<D> collection, Function<D, ?> function) {
// 从缓存取数据列表
V v = redisTemplate.opsForList().leftPop(KEY);
List<D> list = null;
if (null == v) {
list = new LinkedList<>();
} else {
list = (List<D>) v;
}
for (int i = 0; i < list.size(); i++) {
D data = findCollection(function.apply(list.get(i)), collection, function);
if (null == data) {
// 加入redis
list.add(list.get(i));
} else {
// 更新redis
list.set(i, data);
}
}
// 更新redis
redisTemplate.opsForList().leftPush(KEY, (V) list);
return true;
}
/**
* @param key 标识
* @description: 通过list的形式从redis获取一条数据
* @author: evildoer
* @datetime: 2021/4/1 12:58
*/
public <D> D fetchData(Object key, Function<D, ?> function) {
// 从缓存取数据列表
V v = redisTemplate.opsForList().leftPop(KEY);
return this.findCollection(key, (List<D>) v, function);
}
/**
* @description: 通过key从List形式储存的redis删除一条数据, 返回删除的数据
* @author: evildoer
* @datetime: 2021/4/1 12:58
*/
public <D> D delete(Object key, Function<D, ?> function) {
// 从缓存取数据列表
V v = redisTemplate.opsForList().leftPop(KEY);
List<D> list = (List<D>) v;
if (null == v) {
return null;
} else {
list = (List<D>) v;
}
D result = null;
for (int i = 0; i < list.size(); i++) {
if (function.apply(list.get(i)).equals(key)) {
result = list.remove(i);
break;
}
}
// 更新redis
if (null != result) {
redisTemplate.opsForList().leftPush(KEY, (V) list);
}
return result;
}
/**
* @description: 通过key从List形式储存的redis删除多条数据
* @author: evildoer
* @datetime: 2021/4/1 12:58
*/
public <D> boolean deleteList(Collection<D> collection, Function<D, ?> function) {
// 从缓存取数据列表
V v = redisTemplate.opsForList().leftPop(KEY);
List<D> list = (List<D>) v;
if (null == v) {
return false;
} else {
list = (List<D>) v;
}
boolean result = false;
for (int i = 0; i < list.size(); ) {
if (null != findCollection(function.apply(list.get(i)), collection, function)) {
result = true;
list.remove(i);
continue;
}
i++;
}
// 更新redis
if (result) {
redisTemplate.opsForList().leftPush(KEY, (V) list);
}
return result;
}
/**
* 查看集合内是否有该数据(空返回null)
*/
private <D> D findCollection(Object key, Collection<D> collection, Function<D, ?> function) {
if (null == key || null == collection || collection.isEmpty()) {
return null;
}
AtomicReference<D> result = new AtomicReference<>(null);
collection.forEach(data -> {
if (key.equals(function.apply(data))) {
result.set(data);
}
});
return result.get();
}
/**
* 清空Redis存储的对应KEY的数据
*/
public boolean clear() {
redisTemplate.delete(KEY);
return true;
}
public Integer getSize() {
return size;
}
public void setSize(Integer size) {
this.size = size;
}
}
使用实例:
/**
* @author evildoer
* @since 2021-02-05
*/
@Service
@AllArgsConstructor
public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question> implements IQuestionService {
private final RedisTemplate redisTemplate;
/**
* @description: 添加一个数据到redis
* @author: evildoer
* @datetime: 2021/4/1 12:49
*/
boolean saveOrUpdateRedis(QuestionVo data){
// 以hash形式存储
RedisUtils<String, QuestionVo> redisUtils = new RedisUtils<String, QuestionVo>(RedisConstants.QUESTION_KEY, redisTemplate);
return redisUtils.saveOrUpdateToRedis(data, QuestionVo::getId);
}
/**
* @description: 添加一个集合数据到redis
*/
boolean saveOrUpdateRedis(List<QuestionVo> list){
// 以hash形式存储
RedisUtils<String, QuestionVo> redisUtils = new RedisUtils<String, QuestionVo>(RedisConstants.QUESTION_KEY, redisTemplate);
return redisUtils.saveOrUpdateCollectionToRedis(list, QuestionVo::getId);
}
/**
* @description: 从redis获取一条数据
*/
QuestionVo fetchData(Object key){
// 以hash形式存储
RedisUtils<String, QuestionVo> redisUtils = new RedisUtils<String, QuestionVo>(RedisConstants.QUESTION_KEY, redisTemplate);
return redisUtils.fetchData(key);
}
/**
* @description: 从redis删除一个数据
*/
QuestionVo deleteData(Object key){
// 以hash形式存储
RedisUtils<String, QuestionVo> redisUtils = new RedisUtils<String, QuestionVo>(RedisConstants.QUESTION_KEY, redisTemplate);
return redisUtils.delete(key);
}
/**
* @description: 从redis删除多个数据
*/
boolean deleteBatch(Collection<QuestionVo> collection){
// 以hash形式存储
RedisUtils<String, QuestionVo> redisUtils = new RedisUtils<String, QuestionVo>(RedisConstants.QUESTION_KEY, redisTemplate);
return redisUtils.deleteBatch(collection, QuestionVo::getId);
}
}
3)封装类3:
@Component
public class RedisService {
@Resource
public RedisTemplate redisTemplate;
public RedisTemplate getRedisTemplate(){return redisTemplate;}
/**
* 缓存基本的对象,Integer、String、实体类等
*
* @param key 缓存的键值
* @param value 缓存的值
*/
public <T> void setCacheObject(final String key, final T value) {
redisTemplate.opsForValue().set(key, value);
}
/**
* 缓存基本的对象,Integer、String、实体类等
*
* @param key 缓存的键值
* @param value 缓存的值
* @param timeout 时间
* @param timeUnit 时间颗粒度
*/
public <T> void setCacheObject(final String key, final T value, final Long timeout, final TimeUnit timeUnit) {
redisTemplate.opsForValue().set(key, value, timeout, timeUnit);
}
/**
* 设置有效时间
*
* @param key Redis键
* @param timeout 超时时间
* @return true=设置成功;false=设置失败
*/
public boolean expire(final String key, final long timeout) {
return expire(key, timeout, TimeUnit.SECONDS);
}
/**
* 设置有效时间
*
* @param key Redis键
* @param timeout 超时时间
* @param unit 时间单位
* @return true=设置成功;false=设置失败
*/
public boolean expire(final String key, final long timeout, final TimeUnit unit) {
return redisTemplate.expire(key, timeout, unit);
}
/**
* 判断 key是否存在
*
* @param key 键
* @return true 存在 false不存在
*/
public Boolean hasKey(String key) {
return redisTemplate.hasKey(key);
}
/**
* 获得缓存的基本对象。
*
* @param key 缓存键值
* @return 缓存键值对应的数据
*/
public <T> T getCacheObject(final String key) {
ValueOperations<String, T> operation = redisTemplate.opsForValue();
return operation.get(key);
}
/**
* 删除单个对象
*
* @param key
*/
public boolean deleteObject(final String key) {
return redisTemplate.delete(key);
}
/**
* 删除集合对象
*
* @param collection 多个对象
* @return
*/
public long deleteObject(final Collection collection) {
return redisTemplate.delete(collection);
}
/**
* 缓存List数据
*
* @param key 缓存的键值
* @param dataList 待缓存的List数据
* @return 缓存的对象
*/
public <T> long setCacheList(final String key, final List<T> dataList) {
Long count = redisTemplate.opsForList().rightPushAll(key, dataList);
return count == null ? 0 : count;
}
/**
* 获得缓存的list对象
*
* @param key 缓存的键值
* @return 缓存键值对应的数据
*/
public <T> List<T> getCacheList(final String key) {
return redisTemplate.opsForList().range(key, 0, -1);
}
/**
* 缓存Set
*
* @param key 缓存键值
* @param dataSet 缓存的数据
* @return 缓存数据的对象
*/
public <T> BoundSetOperations<String, T> setCacheSet(final String key, final Set<T> dataSet) {
BoundSetOperations<String, T> setOperation = redisTemplate.boundSetOps(key);
Iterator<T> it = dataSet.iterator();
while (it.hasNext()) {
setOperation.add(it.next());
}
return setOperation;
}
/**
* 获得缓存的set
*
* @param key
* @return
*/
public <T> Set<T> getCacheSet(final String key) {
return redisTemplate.opsForSet().members(key);
}
/**
* 缓存Map
*
* @param key
* @param dataMap
*/
public <T> void setCacheMap(final String key, final Map<String, T> dataMap) {
if (dataMap != null) {
redisTemplate.opsForHash().putAll(key, dataMap);
}
}
/**
* 获得缓存的Map
*
* @param key
* @return
*/
public <T> Map<String, T> getCacheMap(final String key) {
return redisTemplate.opsForHash().entries(key);
}
/**
* 往Hash中存入数据
*
* @param key Redis键
* @param hKey Hash键
* @param value 值
*/
public <T> void setCacheMapValue(final String key, final String hKey, final T value) {
redisTemplate.opsForHash().put(key, hKey, value);
}
/**
* 获取Hash中的数据
*
* @param key Redis键
* @param hKey Hash键
* @return Hash中的对象
*/
public <T> T getCacheMapValue(final String key, final String hKey) {
HashOperations<String, String, T> opsForHash = redisTemplate.opsForHash();
return opsForHash.get(key, hKey);
}
/**
* 获取多个Hash中的数据
*
* @param key Redis键
* @param hKeys Hash键集合
* @return Hash对象集合
*/
public <T> List<T> getMultiCacheMapValue(final String key, final Collection<Object> hKeys) {
return redisTemplate.opsForHash().multiGet(key, hKeys);
}
/**
* 获得缓存的基本对象列表
*
* @param pattern 字符串前缀
* @return 对象列表
*/
public Collection<String> keys(final String pattern) {
return redisTemplate.keys(pattern);
}
}