需求原因
在实际项目中需要两个dbindex一个储存用户基本信息另一个存储通过redisson实现订单延时过期的信息,如果放在同一个dbindex,看起来比较乱不好管理。
解决方案 (开整)
引入pom
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<exclusions>
<exclusion>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
创建redis基本信息
#redis的相关配置
redis:
# redis服务器地址(默认为loaclhost)
# host: 59.110.62.123
host: 127.0.0.1
# redis端口(默认为6379)
port: 6379
# redis访问密码(默认为空)
password:
# 最大空闲连接数(默认为8,负数表示无限)
max-idle: 8
# 最小空闲连接数(默认为0,该值只有为正数才有用)
min-idle: 2
# 最大可用连接数(默认为8,负数表示无限)
max-active: 8
# 从连接池中获取连接最大等待时间(默认为-1,单位为毫秒,负数表示无限)
max-wait: 800
testOnBorrow: true
# redis连接超时时间(单位毫秒)
timeout: 300000
#userInfo DB
userInfoDb: 0
#sessionCode DB
sessionCodeDb: 1
创建redis工具
@Component
public class RedisUtils {
private static final Logger LOGGER = LoggerFactory.getLogger(CancelOrderService.class);
@Value("${spring.redis.host}")
private String hostName;
@Value("${spring.redis.port}")
private int port;
@Value("${spring.redis.password}")
private String passWord;
@Value("${spring.redis.max-idle}")
private int maxIdl;
@Value("${spring.redis.min-idle}")
private int minIdl;
@Value("${spring.redis.timeout}")
private int timeout;
@Value("${spring.redis.userInfoDb}")
private int userInfoDb;
@Value("${spring.redis.sessionCodeDb}")
private int sessionCodeDb;
public static Map<Integer, RedisTemplate<Serializable, Object>> redisTemplateMap = new HashMap<>();
@PostConstruct
public void initRedisTemp() throws Exception {
LOGGER.info("###### START 初始化 Redis 连接池 START ######");
redisTemplateMap.put(userInfoDb, redisTemplateObject(userInfoDb));
redisTemplateMap.put(sessionCodeDb, redisTemplateObject(sessionCodeDb));
LOGGER.info("###### END 初始化 Redis 连接池 END ######");
}
public RedisTemplate<Serializable, Object> redisTemplateObject(Integer dbIndex) throws Exception {
RedisTemplate<Serializable, Object> redisTemplateObject = new RedisTemplate<Serializable, Object>();
redisTemplateObject.setConnectionFactory(redisConnectionFactory(jedisPoolConfig(), dbIndex));
setSerializer(redisTemplateObject);
redisTemplateObject.afterPropertiesSet();
return redisTemplateObject;
}
/**
* 连接池配置信息
*
* @return
*/
public JedisPoolConfig jedisPoolConfig() {
JedisPoolConfig poolConfig = new JedisPoolConfig();
//最大连接数
poolConfig.setMaxIdle(maxIdl);
//最小空闲连接数
poolConfig.setMinIdle(minIdl);
poolConfig.setTestOnBorrow(true);
poolConfig.setTestOnReturn(true);
poolConfig.setTestWhileIdle(true);
poolConfig.setNumTestsPerEvictionRun(10);
poolConfig.setTimeBetweenEvictionRunsMillis(60000);
//当池内没有可用的连接时,最大等待时间
poolConfig.setMaxWaitMillis(10000);
//------其他属性根据需要自行添加-------------
return poolConfig;
}
/**
* jedis连接工厂
*
* @param jedisPoolConfig
* @return
*/
public RedisConnectionFactory redisConnectionFactory(JedisPoolConfig jedisPoolConfig, int db) {
//单机版jedis
RedisStandaloneConfiguration redisStandaloneConfiguration =
new RedisStandaloneConfiguration();
//设置redis服务器的host或者ip地址
redisStandaloneConfiguration.setHostName(hostName);
//设置默认使用的数据库
redisStandaloneConfiguration.setDatabase(db);
//设置密码
redisStandaloneConfiguration.setPassword(RedisPassword.of(passWord));
//设置redis的服务的端口号
redisStandaloneConfiguration.setPort(port);
//获得默认的连接池构造器(怎么设计的,为什么不抽象出单独类,供用户使用呢)
JedisClientConfiguration.JedisPoolingClientConfigurationBuilder jpcb =
(JedisClientConfiguration.JedisPoolingClientConfigurationBuilder) JedisClientConfiguration.builder();
//指定jedisPoolConifig来修改默认的连接池构造器(真麻烦,滥用设计模式!)
jpcb.poolConfig(jedisPoolConfig);
//通过构造器来构造jedis客户端配置
JedisClientConfiguration jedisClientConfiguration = jpcb.build();
//单机配置 + 客户端配置 = jedis连接工厂
return new JedisConnectionFactory(redisStandaloneConfiguration, jedisClientConfiguration);
}
private void setSerializer(RedisTemplate<Serializable, Object> template) {
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(
Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
template.setKeySerializer(template.getStringSerializer());
template.setValueSerializer(jackson2JsonRedisSerializer);
template.setHashValueSerializer(jackson2JsonRedisSerializer);
//在使用String的数据结构的时候使用这个来更改序列化方式
RedisSerializer<String> stringSerializer = new StringRedisSerializer();
template.setKeySerializer(stringSerializer);
template.setValueSerializer(stringSerializer);
template.setHashKeySerializer(stringSerializer);
template.setHashValueSerializer(stringSerializer);
}
/**
* 根据db 获取对应的redisTemplate实例
*
* @param db
* @return
*/
public RedisTemplate<Serializable, Object> getRedisTemplateByDb(int db) {
return redisTemplateMap.get(db);
}
/**
* 读取缓存
*
* @param key
* @return
*/
public String get(final String key, int db) {
RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb( db);
String result = null;
ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
result = (String) operations.get(key);
return result;
}
/**
* 写入缓存
*/
public boolean set(final String key, String value, int db) {
RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
boolean result = false;
try {
ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
operations.set(key, value);
result = true;
} catch (Exception e) {
LOGGER.error("set cache error", e);
} finally {
RedisConnectionUtils.unbindConnection(redisTemplate.getConnectionFactory());
}
return result;
}
/**
* 判断缓存是否存在
*/
public boolean hasKey(final String key, int db) {
RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
boolean result = false;
try {
result = redisTemplate.hasKey(key);
} catch (Exception e) {
LOGGER.error("hasKey cache error", e);
} finally {
RedisConnectionUtils.unbindConnection(redisTemplate.getConnectionFactory());
}
return result;
}
/**
* 更新缓存
*/
public boolean getAndSet(final String key, String value, int db) {
RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb( db);
boolean result = false;
try {
ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
operations.getAndSet(key, value);
result = true;
} catch (Exception e) {
LOGGER.error("getAndSet cache error", e);
} finally {
RedisConnectionUtils.unbindConnection(redisTemplate.getConnectionFactory());
}
return result;
}
/**
* 删除缓存
*/
public boolean delete(final String key, int db) {
RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb( db);
boolean result = false;
try {
redisTemplate.delete(key);
result = true;
} catch (Exception e) {
LOGGER.error("delete cache error", e);
} finally {
RedisConnectionUtils.unbindConnection(redisTemplate.getConnectionFactory());
}
return result;
}
/**
* 根据KEY值设置过期时间
*/
public boolean exprie(String key, int seconds, int db) {
RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
boolean result = false;
try {
redisTemplate.expire(key, seconds, TimeUnit.SECONDS);
result = true;
} catch (Exception e) {
LOGGER.error("expire cache error", e);
} finally {
RedisConnectionUtils.unbindConnection(redisTemplate.getConnectionFactory());
}
return result;
}
}
调用redis工具类
public class UserServiceImpl implements UserService {
@Autowired
private RedisUtils redisUtils;
@Override
public RetObj sendSMSByPhone(String phoneNumber) throws Exception {
StringBuffer stringBufferTime = new StringBuffer(15).append(phoneNumber).append("Time");
redisUtils.set(stringBufferTime.toString(), String.valueOf(System.currentTimeMillis()), 0);
redisUtils.exprie(stringBuffer.toString(), 300, 0);
return RetObj.success("发送验证码成功");
}
}
解决方案完成,有什么问题提问