实现原理
- 需要配置好两个数据源,创建两个RedisTemplate
- 在配置类中注入两个RedisConnectionFactory,分别创建对应的RedisTemplate进行操作
详解
配置数据源
我这里是在之前已有一个配置下面另外加了一个
spring:
redis:
# 地址
host: localhost
# 端口,默认为6379
port: 6379
# 数据库索引
database: 0
# 密码
password: xxxx
# 连接超时时间
timeout: 10s
lettuce:
pool:
# 连接池中的最小空闲连接
min-idle: 0
# 连接池中的最大空闲连接
max-idle: 8
# 连接池的最大数据库连接数
max-active: 8
# #连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: -1ms
#第二数据源
second:
host: 127.0.0.1
port: 6379
password: xxx
创建配置文件
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisPassword;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
@Configuration
public class RedisConfigs {
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.port}")
private int port;
@Value("${spring.redis.password}")
private String password;
@Value("${spring.redis.second.host}")
private String secondHost;
@Value("${spring.redis.second.port}")
private int secondPort;
@Value("${spring.redis.second.password}")
private String secondPassword;
@Bean(name = "redisConnectionFactory")
@Primary //默认选择这个数据源进行执行
@Qualifier("redisConnectionFactory")
public RedisConnectionFactory redisConnectionFactory() {
RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();
config.setHostName(host);
config.setPort(port);
config.setPassword(RedisPassword.of(password));
return new JedisConnectionFactory(config);
}
@Bean(name = "secondRedisConnectionFactory")
@Qualifier("secondRedisConnectionFactory")
public RedisConnectionFactory secondRedisConnectionFactory() {
RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();
config.setHostName(secondHost);
config.setPort(port);
config.setPassword(RedisPassword.of(secondPassword));
return new JedisConnectionFactory(config);
}
}
创建工具类
注入配置类中的RedisConnectionFactory分别生成对应的RedisTemplate,然后进行操作就可以啦
import com.bdtd.limit.common.config.FastJson2JsonRedisSerializer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Component;
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 {
private final RedisConnectionFactory redisConnectionFactory;
private final RedisConnectionFactory secondRedisConnectionFactory;
@Autowired
public RedisUtil(RedisConnectionFactory redisConnectionFactory,
@Qualifier("secondRedisConnectionFactory")
RedisConnectionFactory secondRedisConnectionFactory) {
this.redisConnectionFactory = redisConnectionFactory;
this.secondRedisConnectionFactory = secondRedisConnectionFactory;
}
public RedisTemplate<String, Object> getRedisTemplate() {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
FastJson2JsonRedisSerializer serializer = new FastJson2JsonRedisSerializer(Object.class);
// 使用StringRedisSerializer来序列化和反序列化redis的key值
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(serializer);
// Hash的key也采用StringRedisSerializer的序列化方式
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(serializer);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
public RedisTemplate<String, Object> getSecondRedisTemplate() {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(secondRedisConnectionFactory);
FastJson2JsonRedisSerializer serializer = new FastJson2JsonRedisSerializer(Object.class);
// 使用StringRedisSerializer来序列化和反序列化redis的key值
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(serializer);
// Hash的key也采用StringRedisSerializer的序列化方式
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(serializer);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
/**
* 第一数据源
* 缓存基本的对象,Integer、String、实体类等
*
* @param key 缓存的键值
* @param value 缓存的值
*/
public <T> void setCacheObject(final String key, final T value)
{
getRedisTemplate().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 Integer timeout, final TimeUnit timeUnit)
{
getRedisTemplate().opsForValue().set(key, value, timeout, timeUnit);
}
/**
* 第一数据源
* 设置有效时间
*
* @param key Redis键
* @param timeout 超时时间
* @param unit 时间单位
* @return true=设置成功;false=设置失败
*/
public boolean expire(final String key, final long timeout, final TimeUnit unit)
{
return getRedisTemplate().expire(key, timeout, unit);
}
/**
* 第一数据源
* 判断 key是否存在
*
* @param key 键
* @return true 存在 false不存在
*/
public Boolean hasKey(String key)
{
return getRedisTemplate().hasKey(key);
}
/**
* 第一数据源
* 获得缓存的基本对象。
*
* @param key 缓存键值
* @return 缓存键值对应的数据
*/
public Object getCacheObject(final String key)
{
ValueOperations<String, Object> operation = getRedisTemplate().opsForValue();
return operation.get(key);
}
/**
* 第一数据源
* 删除单个对象
*
* @param key
*/
public boolean deleteObject(final String key)
{
return getRedisTemplate().delete(key);
}
/**
* 第一数据源
* 删除集合对象
*
* @param collection 多个对象
* @return
*/
public boolean deleteObject(final Collection collection)
{
return getRedisTemplate().delete(collection) > 0;
}
/**
* 第一数据源
* 缓存List数据
*
* @param key 缓存的键值
* @param dataList 待缓存的List数据
* @return 缓存的对象
*/
public <T> long setCacheList(final String key, final List<T> dataList)
{
Long count = getRedisTemplate().opsForList().rightPushAll(key, dataList);
return count == null ? 0 : count;
}
/**
* 第一数据源
* 获得缓存的list对象
*
* @param key 缓存的键值
* @return 缓存键值对应的数据
*/
public <T> List<T> getCacheList(final String key)
{
return (List<T>) getRedisTemplate().opsForList().range(key, 0, -1);
}
/**
* 第一数据源
* 缓存Map
*
* @param key
* @param dataMap
*/
public <T> void setCacheMap(final String key, final Map<String, T> dataMap)
{
if (dataMap != null) {
getRedisTemplate().opsForHash().putAll(key, dataMap);
}
}
/**
* 第一数据源
* 获得缓存的Map
*
* @param key
* @return
*/
public <T> Map<Object, Object> getCacheMap(final String key)
{
return getRedisTemplate().opsForHash().entries(key);
}
/**
* 第二数据源
* 缓存基本的对象,Integer、String、实体类等
*
* @param key 缓存的键值
* @param value 缓存的值
*/
public <T> void setSencondCacheObject(final String key, final T value)
{
getSecondRedisTemplate().opsForValue().set(key, value);
}
/**
* 第二数据源
* 缓存基本的对象,Integer、String、实体类等
*
* @param key 缓存的键值
* @param value 缓存的值
* @param timeout 时间
* @param timeUnit 时间颗粒度
*/
public <T> void setSencondCacheObject(final String key, final T value, final Integer timeout, final TimeUnit timeUnit)
{
getSecondRedisTemplate().opsForValue().set(key, value, timeout, timeUnit);
}
/**
* 第二数据源
* 设置有效时间
*
* @param key Redis键
* @param timeout 超时时间
* @param unit 时间单位
* @return true=设置成功;false=设置失败
*/
public boolean sencondExpire(final String key, final long timeout, final TimeUnit unit)
{
return getSecondRedisTemplate().expire(key, timeout, unit);
}
/**
* 第二数据源
* 判断 key是否存在
*
* @param key 键
* @return true 存在 false不存在
*/
public Boolean sencondHasKey(String key)
{
return getSecondRedisTemplate().hasKey(key);
}
/**
* 第二数据源
* 获得缓存的基本对象。
*
* @param key 缓存键值
* @return 缓存键值对应的数据
*/
public Object getSencondCacheObject(final String key)
{
ValueOperations<String, Object> operation = getSecondRedisTemplate().opsForValue();
return operation.get(key);
}
/**
* 第一数据源
* 删除单个对象
*
* @param key
*/
public boolean deleteSencondObject(final String key)
{
return getSecondRedisTemplate().delete(key);
}
/**
* 第二数据源
* 删除集合对象
*
* @param collection 多个对象
* @return
*/
public boolean deleteSencondObject(final Collection collection)
{
return getSecondRedisTemplate().delete(collection) > 0;
}
/**
* 第二数据源
* 缓存List数据
*
* @param key 缓存的键值
* @param dataList 待缓存的List数据
* @return 缓存的对象
*/
public <T> long setSencondCacheList(final String key, final List<T> dataList)
{
Long count = getSecondRedisTemplate().opsForList().rightPushAll(key, dataList);
return count == null ? 0 : count;
}
/**
* 第二数据源
* 获得缓存的list对象
*
* @param key 缓存的键值
* @return 缓存键值对应的数据
*/
public <T> List<T> getSencondCacheList(final String key)
{
return (List<T>) getSecondRedisTemplate().opsForList().range(key, 0, -1);
}
/**
* 第二数据源
* 缓存Map
*
* @param key
* @param dataMap
*/
public <T> void setSencondCacheMap(final String key, final Map<String, T> dataMap)
{
if (dataMap != null) {
getSecondRedisTemplate().opsForHash().putAll(key, dataMap);
}
}
/**
* 第二数据源
* 获得缓存的Map
*
* @param key
* @return
*/
public <T> Map<Object, Object> getSencondCacheMap(final String key)
{
return getSecondRedisTemplate().opsForHash().entries(key);
}
}
Redis使用FastJson序列化
import java.nio.charset.Charset;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONReader;
import com.alibaba.fastjson2.JSONWriter;
/**
* Redis使用FastJson序列化
*
*/
public class FastJson2JsonRedisSerializer<T> implements RedisSerializer<T>
{
public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
private Class<T> clazz;
public FastJson2JsonRedisSerializer(Class<T> clazz)
{
super();
this.clazz = clazz;
}
@Override
public byte[] serialize(T t) throws SerializationException
{
if (t == null)
{
return new byte[0];
}
return JSON.toJSONString(t, JSONWriter.Feature.WriteClassName).getBytes(DEFAULT_CHARSET);
}
@Override
public T deserialize(byte[] bytes) throws SerializationException
{
if (bytes == null || bytes.length <= 0)
{
return null;
}
String str = new String(bytes, DEFAULT_CHARSET);
return JSON.parseObject(str, clazz, JSONReader.Feature.SupportAutoType);
}
}