前言
redis是一款开源的Key-Value数据库,运行在内存中,由C语言编写。企业开发通常采用Redis来实现缓存。
RedisTemplate是什么?
RedisTemplate是Spring Data Redis提供给用户的最高级的抽象客户端,用户可直接通过RedisTemplate进行多种操作。
spring-data-redis针对jedis提供了如下功能:
- 连接池自动管理,提供了一个高度封装的“RedisTemplate”类
- 针对jedis客户端中大量api进行了归类封装,将同一类型操作封装为operation接口
ValueOperations:简单K-V操作
SetOperations:set类型数据操作
ZSetOperations:zset类型数据操作
HashOperations:针对map类型的数据操作
ListOperations:针对list类型的数据操作
一、SpringBoot整合Redis
1.引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2.配置连接信息
spring:
redis:
host: 127.0.0.1
port: 6379
password: 123456
jedis:
pool:
max-active: 8
max-wait: -1
max-idle: 500
min-idle: 0
lettuce:
shutdown-timeout: 0
3.测试
@Autowired
private RedisTemplate redisTemplate;
public void set() {
redisTemplate.opsForValue().set("key", "value");
System.out.println(redisTemplate.opsForValue().get("key"));
}
二、redis序列化
声明一个redisTemplate,测试是否可以把数据保存到redis,并从redis取出。
发现实际保存的内容如下:
key-value:
key:\xAC\xED\x00\x05t\x00\x08test_key
value:\xAC\xED\x00\x05t\x00\x0Dtest_value111
hash:
key:\xAC\xED\x00\x05t\x00\x0Epush_frequency
hashkey:\xAC\xED\x00\x05t\x00\x04date
hashvalue:\xAC\xED\x00\x05t\x00\x0A2022-01-06
所有的key和value的原始字符前,都加了一串字符,如果不进行序列化的话,默认使用JdkSerializationRedisSerializer进行数据序列化就会加上这串字符。把任何数据保存到redis中时,都需要进行序列化。
序列化方法
StringRedisSerializer:对String数据进行序列化。序列化后,保存到Redis中的数据,不会有像上面的“\xAC\xED\x00\x05t\x00\x09”多余字符。就是"frequency".
Jackson2JsonRedisSerializer:用Jackson2,将对象序列化成Json。这个Serializer功能很强大,但在现实中,是否需要这样使用,要多考虑。一旦这样使用后,要修改对象的一个属性值时,就需要把整个对象都读取出来,再保存回去。
JdkSerializationRedisSerializer:使用Java序列化。结果就像最上面的样子。
GenericToStringSerializer:使用Spring转换服务进行序列化。使用方法和StringRedisSerializer相比,StringRedisSerializer只能直接对String类型的数据进行操作,如果要被序列化的数据不是String类型的,需要转换成String类型,例如:String.valueOf()。但使用GenericToStringSerializer的话,不需要进行转换,直接由String帮我们进行转换。但这样的话,也就定死了序列化前和序列化后的数据类型,例如:template.setValueSerializer(new GenericToStringSerializer<Long>(Long.class));我们只能用对Long型进行序列化和反序列化。
OxmSerializer:使用SpringO/X映射的编排器和解排器实现序列化,用于XML序列化。
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(connectionFactory);
//使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值(默认使用JDK的序列化方式)
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
//使用StringRedisSerializer来序列化和反序列化redis的key值
RedisSerializer redisSerializer = new StringRedisSerializer();
//key
redisTemplate.setKeySerializer(redisSerializer);
redisTemplate.setHashKeySerializer(redisSerializer);
//value
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
三、RedisTemplate的直接方法
public class RedisUtil {
@Autowired
private RedisTemplate redisTemplate;
/**
*
* @Title: set
* @Description: 写入缓存
* @param key
* @param value
* @return
* @author mario
* @return: boolean
*/
public boolean set(final String key, Object value) {
boolean result = false;
try {
ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
operations.set(key, value);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
*
* @Title: increment
* @Description: 计数
* @param key
* @param value
* @return
* @author mario
* @return: boolean
*/
public long increment(final String key, Long value) {
long result = 0;
try {
ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
result = operations.increment(key, value);
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
*
* @Title: set
* @Description: 写入缓存设置时效时间
* @param key
* @param value
* @param expireTime
* @return
* @author mario
* @return: boolean
*/
public boolean set(final String key, Object value, Long expireTime) {
boolean result = false;
try {
ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
operations.set(key, value);
redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}/**
*
* @Title: set
* @Description: 写入缓存设置时效时间
* @param key
* @param value
* @param expireTime
* @return
* @author mario
* @return: boolean
*/
public boolean set(final String key, Object value, Long expireTime,TimeUnit t) {
boolean result = false;
try {
ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
operations.set(key, value);
redisTemplate.expire(key, expireTime,t);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
*
* @Title: remove
* @Description: 批量删除对应的value
* @param keys
* @author mario
* @return: void
*/
public void remove(final String... keys) {
for (String key : keys) {
remove(key);
}
}
/**
*
* @Title: removePattern
* @Description: 批量删除key
* @param pattern
* @author mario
* @return: void
*/
public void removePattern(final String pattern) {
Set<Serializable> keys = redisTemplate.keys(pattern);
if (keys.size() > 0)
redisTemplate.delete(keys);
}
/**
*
* @Title: remove
* @Description: 删除对应的value
* @param key
* @author mario
* @return: void
*/
public void remove(final String key) {
if (exists(key)) {
redisTemplate.delete(key);
}
}
/**
*
* @Title: exists
* @Description: 判断缓存中是否有对应的value
* @param key
* @return
* @author mario
* @return: boolean
*/
public boolean exists(final String key) {
return redisTemplate.hasKey(key);
}
/**
*
* @Title: get
* @Description: 读取
* @param key
* @return
* @author mario
* @return: Object
*/
public Object get(final String key) {
Object result = null;
ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
result = operations.get(key);
return result;
}
/**
*
* @Title: SetKeyExpireTime
* @Description: 设置key的过期时间
* @param key
* @param expireTime
* @author mario
* @return: void
*/
public void SetKeyExpireTime(String key,Long expireTime ) {
redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
}
/**
*
* @Title: hmSet
* @Description: 哈希添加数据
* @param key
* @param hashKey
* @param value
* @author mario
* @return: void
*/
public void hmSet(String key, Object hashKey, Object value) {
HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
hash.put(key, hashKey, value);
}
/**
*
* @Title: hmSize
* @Description: 哈希获取key数据大小
* @param key
* @return
* @author mario
* @return: Long
*/
public Long hmSize(String key) {
HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
return hash.size(key);
}
/**
*
* @Title: hmGet
* @Description: 哈希获取数据
* @param key
* @param hashKey
* @return
* @author mario
* @return: Object
*/
public Object hmGet(String key, Object hashKey) {
HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
return hash.get(key, hashKey);
}
/**
*
* @Title: hmGet
* @Description: 通过key+哈希获取集合
* @param key
* @param hashKeys
* @return
* @author mario
* @return: List
*/
public List hmGet(String key, Collection< Object> hashKeys) {
HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
return hash.multiGet(key, hashKeys);
}
/**
*
* @Title: hmGetHshKeys
* @Description: 获取hashKey的集合
* @param key
* @return
* @author mario
* @return: Set<Object>
*/
public Set<Object> hmGetHshKeys(String key) {
HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
return hash.keys(key);
}
/**
*
* @Title: hmDelete
* @Description: 哈希删除数据
* @param key
* @param hashKeys
* @return
* @author mario
* @return: Object
*/
public Object hmDelete(String key, Object... hashKeys) {
HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
return hash.delete(key, hashKeys);
}
/**
*
* @Title: lPush
* @Description: 列表添加
* @param k
* @param v
* @author mario
* @return: void
*/
public void lPush(String k, Object v) {
ListOperations<String, Object> list = redisTemplate.opsForList();
list.rightPush(k, v);
}
/**
*
* @Title: lPushAll
* @Description: 列表添加集合
* @param key
* @param values
* @author mario
* @return: void
*/
public void lPushAll(String key, List<? extends Object> values) {
ListOperations<String, Object> list = redisTemplate.opsForList();
list.rightPushAll(key, values);
}
/**
*
* @Title: lRange
* @Description: 列表获取
* @param k
* @param l
* @param l1
* @return
* @author mario
* @return: List<? extends Object>
*/
public List<? extends Object> lRange(String k, long l, long l1) {
ListOperations<String, List<? extends Object>> list = redisTemplate.opsForList();
return list.range(k, l, l1);
}
/**
*
* @Title: add
* @Description: 集合添加
* @param key
* @param value
* @author mario
* @return: void
*/
public void add(String key, Object value) {
SetOperations<String, Object> set = redisTemplate.opsForSet();
set.add(key, value);
}
/**
*
* @Title: setMembers
* @Description: 集合获取
* @param key
* @return
* @author mario
* @return: Set<Object>
*/
public Set<Object> setMembers(String key) {
SetOperations<String, Object> set = redisTemplate.opsForSet();
return set.members(key);
}
/**
*
* @Title: zAdd
* @Description: 有序集合添加
* @param key
* @param value
* @param scoure
* @author mario
* @return: void
*/
public void zAdd(String key, Object value, double scoure) {
ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
zset.add(key, value, scoure);
}
/**
*
* @Title: zAddAll
* @Description: 一次性添加set集合
* @param key
* @param setValue
* @param scoure
* @author mario
* @return: void
*/
public void zAddAll(String key, Set<Object> setValue, double scoure) {
for(Object object : setValue) {
zAdd(key, object, scoure);
}
}
/**
*
* @Title: rangeByScore
* @Description: 有序集合获取
* @param key
* @param scoure
* @param scoure1
* @return
* @author mario
* @return: Set<Object>
*/
public Set<Object> rangeByScore(String key, double scoure, double scoure1) {
ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
return zset.rangeByScore(key, scoure, scoure1);
}
/**
*
* @Title: removeRangeByScore
* @Description: 根据分数范围删除ZSet集合中的元素(minScoure和maxSource相同,则是根据分数精确删除)
* @param key
* @param minScoure
* @param maxSource
* @return
* @author mario
* @return: long
*/
public long removeRangeByScore(String key, double minScoure, double maxSource) {
ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
return zset.removeRangeByScore(key, minScoure, maxSource);
}
public void zRemove(String key,Object... values) {
ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
zset.remove(key, values);
}
/**
* 获取 过期时间
* @param key
* @param timeUnit
*/
public Long getKeyExpireTime(String key,TimeUnit timeUnit) {
return redisTemplate.getExpire(key, timeUnit);
}
}