一、添加依赖
gradle方式:
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-data-redis', version: '2.7.18'
二、配置redis的序列化
redis默认使用JDKSerializer序列化,需要类都implements Serializer才能使用,修改量比较大,因此推荐使用第三方的序列化。
redis本身实现的序列化器如下:
GenericJackson2JsonRedisSerializer:在序列化时会携带信息,@class字段中会存对应的类信息,但是像JPA的Tuple类型的返回会是个代理类,此时反序列化就会失败。
配置如下:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfiguration {
/**
* redis序列化配置.
*
* @param redisConnectionFactory RedisConnectionFactory
* @return RedisTemplate<String, Object>
*/
@Bean
public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
// 使用 Jackson 提供的通用 Serializer
Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
// String 类型的 key/value 序列化
redisTemplate.setKeySerializer(StringRedisSerializer.UTF_8);
redisTemplate.setValueSerializer(serializer);
// Hash 类型的 key/value 序列化
redisTemplate.setHashKeySerializer(serializer);
redisTemplate.setHashValueSerializer(serializer);
return redisTemplate;
}
}
三、封装redisTemplate
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.ReflectionUtils;
import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* redis封装.
*
* @param <K> 键
* @param <V> 值
*/
@Component
public class RedisTemplateWrap<K, V> {
@Resource
private RedisTemplate<K, V> redisTemplate;
/**
* set数据.
*
* @param key 键
* @param object 值
*/
public void set(K key, V object) {
redisTemplate.opsForValue().set(key, object);
}
/**
* set数据.
*
* @param key 键
* @param addKey 手动追加键
* @param object 值
*/
public void set(K key, String[] addKey, V object) {
redisTemplate.opsForValue().set(addKey(key, addKey, object), object);
}
/**
* set数组对象数据-固定key.
*
* @param key 键
* @param object 值
*/
public <T extends V> void setCollection(K key, Collection<T> object) {
object.forEach(v -> redisTemplate.opsForList().rightPush(key, v));
}
/**
* set数组单个对象数据.
*
* @param key 键
* @param object 值
*/
public <T extends V> void setCollection(K key, T object) {
redisTemplate.opsForList().rightPush(key, object);
}
/**
* 设置数组对象数据-自定义key.
*
* @param key 键
* @param addKey 通过追加Key获取T中的字段值拼接键
* @param object 值
*/
public <T extends V> void setCollection(K key, String[] addKey, Collection<T> object) {
object.forEach(v -> redisTemplate.opsForList().rightPush(addKey(key, addKey, v), v));
}
/**
* 设置HASH数据.
*
* @param key 键
* @param value 值
*/
public void setHash(K key, Map<?, ?> value) {
if (Boolean.TRUE.equals(redisTemplate.hasKey(key))) {
value.forEach((keys, values) -> redisTemplate.opsForHash().putIfAbsent(key, keys, values));
}
redisTemplate.opsForHash().putAll(key, value);
}
/**
* 获取HASH数据.
*
* @param key 键
* @param hashKey 值
*/
public Object getHash(K key, Object hashKey) {
return redisTemplate.opsForHash().get(key, hashKey);
}
/**
* 获取数据.
*
* @param key 键
* @param t 类型
* @return T
*/
public <T> T get(K key, Class<T> t) {
return (T) redisTemplate.opsForValue().get(key);
}
/**
* 获取数据.
*
* @param key 键
* @return V
*/
public V get(K key) {
return redisTemplate.opsForValue().get(key);
}
/**
* 获取所有List数据.
*
* @param key 键
* @return List<V>
*/
public <T> List<T> getList(K key, Class<T> value) {
return (List<T>) redisTemplate.opsForList().range(key, 0, -1);
}
/**
* 拼接Key
*
* @param key 键
* @param v 对象
* @return K
*/
private K addKey(K key, String[] addKey, Object v) {
K ks = key;
if (key instanceof String) {
Class<?> classV = v.getClass();
StringBuilder stringBuilder = new StringBuilder();
Arrays.asList(addKey).forEach(ak -> {
Field field = ReflectionUtils.findField(classV, ak);
if (field != null) {
ReflectionUtils.makeAccessible(field);
Object valueByKey = ReflectionUtils.getField(field, v);
stringBuilder.append(valueByKey);
}
});
ks = (K) (key + stringBuilder.toString());
}
return ks;
}
}