由于工作业务需求,需要在单机redis中做切库处理。一般来说,redis数据库有16个数据库,而且有对应的索引,分别为0-15,如下图
目前的项目时Springboot2.0.5搭建的,当前已经有一个redis工具类了。但是不满足需求,需要修改。
application.yml配置
spring:
redis:
open: true # 是否开启redis缓存 true开启 false关闭
database: 0
host: localhost
port: 6379
password: # 密码(默认为空)
timeout: 6000ms # 连接超时时长(毫秒)
jedis:
pool:
max-active: 1000 # 连接池最大连接数(使用负值表示没有限制)
max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
max-idle: 10 # 连接池中的最大空闲连接
min-idle: 5 # 连接池中的最小空闲连接
redis配置类
@Configuration
public class RedisConfig {
@Autowired
private RedisConnectionFactory factory;
@Bean
public RedisTemplate redisTemplate() {
RedisTemplate redisTemplate = new RedisTemplate<>();
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
redisTemplate.setConnectionFactory(factory);
return redisTemplate;
}
@Bean
public HashOperations hashOperations(RedisTemplate redisTemplate) {
return redisTemplate.opsForHash();
}
@Bean
public ValueOperations valueOperations(RedisTemplate redisTemplate) {
return redisTemplate.opsForValue();
}
@Bean
public ListOperations listOperations(RedisTemplate redisTemplate) {
return redisTemplate.opsForList();
}
@Bean
public SetOperations setOperations(RedisTemplate redisTemplate) {
return redisTemplate.opsForSet();
}
@Bean
public ZSetOperations zSetOperations(RedisTemplate redisTemplate) {
return redisTemplate.opsForZSet();
}
RedisUtils
@Component
public class RedisUtils {
@Autowired
private RedisTemplate redisTemplate;
@Resource(name="redisTemplate")
private ValueOperations valueOperations;
@Resource(name="redisTemplate")
private HashOperations hashOperations;
@Resource(name="redisTemplate")
private ListOperations listOperations;
@Resource(name="redisTemplate")
private SetOperations setOperations;
@Resource(name="redisTemplate")
private ZSetOperations zSetOperations;
/** 默认过期时长,单位:秒 */
public final static long DEFAULT_EXPIRE = 60 * 60 * 24;
/** 不设置过期时长 */
public final static long NOT_EXPIRE = -1;
public void set(String key, Object value, long expire){
valueOperations.set(key, toJson(value));
if(expire != NOT_EXPIRE){
redisTemplate.expire(key, expire, TimeUnit.SECONDS);
}
}
public void set(String key, Object value){
set(key, value, DEFAULT_EXPIRE);
}
public T get(String key, Class clazz, long expire) {
String value = valueOperations.get(key);
if(expire != NOT_EXPIRE){
redisTemplate.expire(key, expire, TimeUnit.SECONDS);
}
return value == null ? null : fromJson(value, clazz);
}
public T get(String key, Class clazz) {
return get(key, clazz, NOT_EXPIRE);
}
public String get(String key, long expire) {
String value = valueOperations.get(key);
if(expire != NOT_EXPIRE){
redisTemplate.expire(key, expire, TimeUnit.SECONDS);
}
return value;
}
public String get(String key) {
return get(key, NOT_EXPIRE);
}
public void delete(String key) {
redisTemplate.delete(key);
}
/**
* Object转成JSON数据
*/
private String toJson(Object object){
if(object instanceof Integer || object instanceof Long || object instanceof Float ||
object instanceof Double || object instanceof Boolean || object instanceof String){
return String.valueOf(object);
}
return JSON.toJSONString(object);
}
/**
* JSON数据,转成Object
*/
private T fromJson(String json, Class clazz){
return JSON.parseObject(json, clazz);
}
Redis切面,用来控制redis开关
@Aspect
@Component
public class RedisAspect {
private Logger logger = LoggerFactory.getLogger(getClass());
//是否开启redis缓存 true开启 false关闭
@Value("${renren.redis.open}")
private boolean open;
@Around("execution(* io.renren.common.utils.RedisUtils.*(..))")
public Object around(ProceedingJoinPoint point) throws Throwable {
Object result = null;
if(open){
try{
result = point.proceed();
}catch (Exception e){
logger.error("redis error", e);
throw new RRException("Redis服务异常");
}
}
return result;
}
以上是最开始的redis工具,但是只能在yml配置文件中配置指定的库,不能动态切库。
参照了这篇文章
spring-data-redis进行选库操作
我自定义了redisTemplate,继承StringRedisTemplate,然后重写了protected RedisConnection方法,然后整合当前的工具类,做了一些修改。但是最后测试的时候报错:
java.lang.UnsupportedOperationException: Selecting a new database not supported due to shared connection. Use separate ConnectionFactorys to work with multiple databases
at org.springframework.data.redis.connection.lettuce.LettuceConnection.select(LettuceConnection.java:640)
at com.xQuant.app.common.utils.RedisUtils.setDbIndex(RedisUtils.java:45)
at com.xQuant.app.common.utils.RedisUtils.set(RedisUtils.java:49)
at com.xQuant.app.common.utils.RedisUtils.set(RedisUtils.java:57)
at com.xQuant.app.XQuantAppApplicationTests.contextLoads(XQuantAppApplicationTests.java:20)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:73)
at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:83)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:89)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:541)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:763)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:463)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:209)
大概意思就是在共享链接情况下不能切换库。
同事在网上找到了一篇这个文章:
Spring cloud 和 Spring Boot 升级到F版和2.x遇到的问题。
这里面有提到遇到上面那个问题:
给出的解决方案是在实例化RedisTemplate时,不再注入RedisConnectionFactory,改为注入LettuceConnectionFactory ,并关闭共享链接。所以修改当前的redis配置和工具类:
修改后的Redis配置
@Configuration
public class RedisConfig {
@Autowired
private LettuceConnectionFactory factory;
@Bean
public RedisTemplate redisTemplate() {
// 关闭共享链接
factory.setShareNativeConnection(false);
RedisTemplate redisTemplate = new RedisTemplate<>();
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new StringRedisSerializer());
redisTemplate.setConnectionFactory(factory);
return redisTemplate;
}
@Bean
public HashOperations hashOperations(RedisTemplate redisTemplate) {
return redisTemplate.opsForHash();
}
@Bean
public ValueOperations valueOperations(RedisTemplate redisTemplate) {
return redisTemplate.opsForValue();
}
@Bean
public ListOperations listOperations(RedisTemplate redisTemplate) {
return redisTemplate.opsForList();
}
@Bean
public SetOperations setOperations(RedisTemplate redisTemplate) {
return redisTemplate.opsForSet();
}
@Bean
public ZSetOperations zSetOperations(RedisTemplate redisTemplate) {
return redisTemplate.opsForZSet();
}
主要修改了两个地方,注入LettuceConnectionFactory ,关闭共享链接
修改后的RedisUtils
/**
* Redis工具类
*
* 封装了对象和字符串的存,取,删除,设置过期时间操作. 所有操作可以指定数据库索引. 存,取可以设置过期时间. 没有设置默认过期时间,存值时尽量设置过期时间
*
* @author chunhui.tan
* @version 创建时间:2018年10月8日 下午3:31:00
*/
@Component
public class RedisUtils {
@Autowired
private RedisTemplate redisTemplate;
@Autowired
private ValueOperations valueOperations;
@Autowired
private HashOperations hashOperations;
@Autowired
private ListOperations listOperations;
@Autowired
private SetOperations setOperations;
@Autowired
private ZSetOperations zSetOperations;
/** 默认过期时长,单位:秒 */
//public final static long DEFAULT_EXPIRE = 60 * 60 * 24;
/** 不设置过期时长 */
public final static long NOT_EXPIRE = -1;
private final static Gson gson = new Gson();
public RedisTemplate getRedisTemplate() {
return redisTemplate;
}
/**
* 插入值-对象,指定数据库索引,指定过期时间
*
* @param key 键
* @param value 值
* @param dbIndex 数据库索引 范围 0-15 默认0
* @param expire 过期时间 单位:秒
*/
public void set(String key, Object value, Integer dbIndex, long expire) {
// 选择数据库
setDbIndex(dbIndex);
valueOperations.set(key, toJson(value));
if (expire != NOT_EXPIRE) {
redisTemplate.expire(key, expire, TimeUnit.SECONDS);
}
}
/**
* 插入值-对象
*
* @param key 键
* @param value 值
* @param dbIndex 数据库索引 范围 0-15 默认0
*/
public void set(String key, Object value, Integer dbIndex) {
set(key, value, dbIndex, NOT_EXPIRE);
}
/**
* 插入值-对象 ,默认0 index数据库
*
* @param key 键
* @param value 值
*/
public void set(String key, Object value) {
set(key, value, 0, NOT_EXPIRE);
}
/**
* 获取值-对象,指定数据库索引,并设置过期时间
*
* @param key 键
* @param clazz 字节码对象
* @param dbIndex 数据库索引 范围 0-15 默认0
* @param expire 过期时间 单位:秒
* @return
*/
public T get(String key, Class clazz, Integer dbIndex, long expire) {
setDbIndex(dbIndex);
String value = valueOperations.get(key);
if (expire != NOT_EXPIRE) {
redisTemplate.expire(key, expire, TimeUnit.SECONDS);
}
return value == null ? null : fromJson(value, clazz);
}
/**
* 取值-对象 指定数据库索引
*
* @param key 键
* @param clazz 字节码对象
* @param dbIndex 数据库索引 范围 0-15 默认0
* @return
*/
public T get(String key, Class clazz, Integer dbIndex) {
return get(key, clazz, dbIndex, NOT_EXPIRE);
}
/**
* 取值-对象
*
* @param key 键
* @param clazz 字节码对象
* @return
*/
public T get(String key, Class clazz) {
return get(key, clazz, 0, NOT_EXPIRE);
}
/**
* 获取值-字符串,指定数据库索引,设置过期时间
*
* @param key 键
* @param dbIndex 数据库索引 范围 0-15 默认0
* @param expire 过期时间 单位:秒
* @return
*/
public String get(String key, Integer dbIndex, long expire) {
setDbIndex(dbIndex);
String value = valueOperations.get(key);
if (expire != NOT_EXPIRE) {
redisTemplate.expire(key, expire, TimeUnit.SECONDS);
}
return value;
}
/**
* 取值-字符串,指定数据库索引
*
* @param key 键
* @param dbIndex 数据库索引 范围 0-15 默认0
* @return
*/
public String get(String key, Integer dbIndex) {
return get(key, dbIndex, NOT_EXPIRE);
}
/**
* 取值-字符串
*
* @param key 键
* @return
*/
public String get(String key) {
return get(key, 0, NOT_EXPIRE);
}
/**
* 删除 指定数据库索引
*
* @param key 键
* @param dbIndex 数据库索引 范围 0-15 默认0
*/
public Boolean delete(String key, Integer dbIndex) {
setDbIndex(dbIndex);
return redisTemplate.delete(key);
}
/**
* 删除
*
* @param key 键
*/
public Boolean delete(String key) {
return delete(key, 0);
}
/**
* 设置过期时间 ,指定数据库索引
*
* @param key 键
* @param dbIndex 数据库索引 范围 0-15 默认0
* @param expire 过期时间 单位:秒
*/
public void expire(String key, Integer dbIndex, int expire) {
setDbIndex(dbIndex);
if (expire != NOT_EXPIRE) {
redisTemplate.expire(key, expire, TimeUnit.SECONDS);
}
}
/**
* 设置过期时间
*
* @param key 键
* @param expire 过期时间 单位:秒
*/
public void expire(String key, int expire) {
expire(key, 0, expire);
}
/**
* Object转成JSON数据
*/
private String toJson(Object object) {
if (object instanceof Integer || object instanceof Long || object instanceof Float || object instanceof Double
|| object instanceof Boolean || object instanceof String) {
return String.valueOf(object);
}
return gson.toJson(object);
}
/**
* JSON数据,转成Object
*/
private T fromJson(String json, Class clazz) {
return gson.fromJson(json, clazz);
}
/**
* 设置数据库索引
*
* @param dbIndex
*/
private void setDbIndex(Integer dbIndex) {
if (dbIndex == null || dbIndex > 15 || dbIndex < 0) {
dbIndex = 0;
}
LettuceConnectionFactory jedisConnectionFactory = (LettuceConnectionFactory) redisTemplate
.getConnectionFactory();
jedisConnectionFactory.setDatabase(dbIndex);
redisTemplate.setConnectionFactory(jedisConnectionFactory);
}
主要修改的了部分方法的参数,增加数据库选择。同事增加了选择数据库方法。
@RunWith(SpringRunner.class)
@SpringBootTest
public class XquantXcrmsApplicationTests {
@Autowired
private RedisUtils redisUtils;
@Test
public void contextLoads() {
List list = new ArrayList<>();
list.add("2333");
list.add("test1");
this.redisUtils.set("哈哈哈", list, 11);
System.out.println(redisUtils.getRedisTemplate().getConnectionFactory().getConnection());
List result = this.redisUtils.get("哈哈哈", List.class, 12);
System.out.println(redisUtils.getRedisTemplate().getConnectionFactory().getConnection());
System.out.println(result);
}
}
分别为往11号库存一次,然后再从12号库去一次。
运行结果如下:
2018-10-18 18:50:36.203 INFO 11456 --- [ main] io.lettuce.core.KqueueProvider : Starting without optional kqueue library
org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory@b01cb8d
org.springframework.data.redis.connection.lettuce.LettuceConnection@38c460e8
---------------------------------
org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory@b01cb8d
org.springframework.data.redis.connection.lettuce.LettuceConnection@4e67cfe1
null
修改测试代码如下
@RunWith(SpringRunner.class)
@SpringBootTest
public class XquantXcrmsApplicationTests {
@Autowired
private RedisUtils redisUtils;
@Test
public void contextLoads() {
List list = new ArrayList<>();
list.add("2333");
list.add("test1");
this.redisUtils.set("哈哈哈", list, 12);
System.out.println(redisUtils.getRedisTemplate().getConnectionFactory());
System.out.println(redisUtils.getRedisTemplate().getConnectionFactory().getConnection());
System.out.println("---------------------------------");
List result = this.redisUtils.get("哈哈哈", List.class, 11);
System.out.println(redisUtils.getRedisTemplate().getConnectionFactory());
System.out.println(redisUtils.getRedisTemplate().getConnectionFactory().getConnection());
System.out.println(result);
}
}
结果
2018-10-18 18:53:02.036 INFO 12524 --- [ main] io.lettuce.core.KqueueProvider : Starting without optional kqueue library
org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory@685d7ba5
org.springframework.data.redis.connection.lettuce.LettuceConnection@16d41725
---------------------------------
org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory@685d7ba5
org.springframework.data.redis.connection.lettuce.LettuceConnection@4df7d9ee
[2333, test1]
观察redis客户端
测试没有问题
实际上用原生的Jedis也是可以实现切库的。
yml文件配置:
spring:
redis:
host: localhost
port: 6379
password:
timeout: 6000ms
jedis:
pool:
max-active: 1000 # 连接池最大连接数(使用负值表示没有限制)
max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
max-idle: 10 # 连接池中的最大空闲连接
min-idle: 5 # 连接池中的最小空闲连接
Jedis配置类
/**
* @author chunhui.tan
* @version 创建时间:2018年10月18日 下午1:42:59
*
*/
@Configuration
public class JedisConfiguration {
/**
* 注入spirng中的读取redis配置的类
*/
@Autowired
private RedisProperties properties;
@Bean
public JedisPool getJedisPool() {
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxIdle(properties.getJedis().getPool().getMaxIdle());
config.setMaxTotal(properties.getJedis().getPool().getMaxActive());
config.setMaxWaitMillis(properties.getJedis().getPool().getMaxWait().toMillis());
JedisPool pool = new JedisPool(config, properties.getHost(), properties.getPort(),
Integer.valueOf(Long.toString(properties.getTimeout().getSeconds())));
return pool;
}
}
Jedis工具类
/**
* @author chunhui.tan
* @version 创建时间:2018年10月18日 下午2:31:35
*
*/
@Component
public class RedisUtils {
@Autowired
private JedisPool jedisPool;
/** 不设置过期时长 */
public final static int NOT_EXPIRE = -1;
private final static Gson gson = new Gson();
/**
* 插入值-对象,指定数据库 指定过期时间
*
* @param key 键
* @param value 值
* @param dbIndex 数据库索引 范围 0-15 默认0
* @param expire 过期时间 单位:秒
*/
public void set(String key, Object value, Integer dbIndex, int expire) {
Jedis jedis = getJedis(dbIndex);
jedis.set(key, toJson(value));
if (expire != NOT_EXPIRE) {
jedis.expire(key, expire);
}
}
/**
* 插入值-对象,指定数据库索引
*
* @param key 键
* @param value 值
* @param dbIndex 数据库索引 范围 0-15,默认0
*/
public void set(String key, Object value, Integer dbIndex) {
set(key, value, dbIndex, NOT_EXPIRE);
}
/**
* 插入值-对象 ,默认0 index数据库
*
* @param key 键
* @param value 值
*/
public void set(String key, Object value) {
set(key, value, 0, NOT_EXPIRE);
}
/**
* 获取值-对象,指定数据库索引,并设置过期时间
*
* @param key 键
* @param clazz 字节码对象
* @param dbIndex 数据库索引 范围 0-15 默认0
* @param expire 过期时间 单位:秒
* @return
*/
public T get(String key, Class clazz, Integer dbIndex, int expire) {
Jedis jedis = getJedis(dbIndex);
try {
String value = jedis.get(key);
if (expire != NOT_EXPIRE) {
jedis.expire(key, expire);
}
return value == null ? null : fromJson(value, clazz);
} finally {
jedis.close();
}
}
/**
* 取值-对象 指定数据库索引
*
* @param key 键
* @param clazz 字节码对象
* @param dbIndex 数据库索引 范围 0-15 默认0
* @return
*/
public T get(String key, Class clazz, Integer dbIndex) {
return get(key, clazz, dbIndex, NOT_EXPIRE);
}
/**
* 取值-对象
*
* @param key 键
* @param clazz 字节码对象
* @return
*/
public T get(String key, Class clazz) {
return get(key, clazz, 0, NOT_EXPIRE);
}
/**
* 取值-字符串,指定数据库索引,设置过期时间
*
* @param key 键
* @param dbIndex 数据库索引 范围 0-15 默认0
* @param expire 过期时间 单位:秒
* @return
*/
public String get(String key, Integer dbIndex, int expire) {
Jedis jedis = getJedis(dbIndex);
try {
String value = jedis.get(key);
if (expire != NOT_EXPIRE) {
jedis.expire(key, expire);
}
return value;
} finally {
jedis.close();
}
}
/**
* 取值-字符串,指定数据库索引
*
* @param key 键
* @param dbIndex 数据库索引 范围 0-15 默认0
* @return
*/
public String get(String key, Integer dbIndex) {
return get(key, dbIndex, NOT_EXPIRE);
}
/**
* 取值-字符串
*
* @param key 键
* @return
*/
public String get(String key) {
return get(key, 0, NOT_EXPIRE);
}
/**
* 删除 指定数据库索引
*
* @param key 键
* @param dbIndex 数据库索引 范围 0-15 默认0
*/
public void delete(String key, Integer dbIndex) {
Jedis jedis = getJedis(dbIndex);
try {
jedis.del(key);
} finally {
jedis.close();
}
}
/**
* 删除
*
* @param key 键
*/
public void delete(String key) {
delete(key, 0);
}
/**
* 设置过期时间
*
* @param key 键
* @param dbIndex 数据库索引 范围 0-15 默认0
* @param expire 过期时间 单位:秒
*/
public void expire(String key, Integer dbIndex, int expire) {
Jedis jedis = getJedis(dbIndex);
try {
if (expire != NOT_EXPIRE) {
jedis.expire(key, expire);
}
} finally {
jedis.close();
}
}
/**
* 设置过期时间
*
* @param key 键
* @param expire 过期时间 单位:秒
*/
public void expire(String key, int expire) {
expire(key, 0, expire);
}
/**
* 获取jedis对象,并指定dbIndex
*
* @param dbIndex
*/
private Jedis getJedis(Integer dbIndex) {
Jedis jedis = jedisPool.getResource();
if (dbIndex == null || dbIndex > 15 || dbIndex < 0) {
dbIndex = 0;
}
jedis.select(dbIndex);
return jedis;
}
/**
* Object转成JSON数据
*/
private String toJson(Object object) {
if (object instanceof Integer || object instanceof Long || object instanceof Float || object instanceof Double
|| object instanceof Boolean || object instanceof String) {
return String.valueOf(object);
}
return gson.toJson(object);
}
/**
* JSON数据,转成Object
*/
private T fromJson(String json, Class clazz) {
return gson.fromJson(json, clazz);
}
里面的核心方法:
/**
* 获取jedis对象,并指定dbIndex
*
* @param dbIndex
*/
private Jedis getJedis(Integer dbIndex) {
Jedis jedis = jedisPool.getResource();
if (dbIndex == null || dbIndex > 15 || dbIndex < 0) {
dbIndex = 0;
}
jedis.select(dbIndex);
return jedis;
}
即在通过注入的JedisPool获取Jedis对象时,指定一下数据库即可
情况redis,然后执行以下代码
@RunWith(SpringRunner.class)
@SpringBootTest
public class XquantTestApplicationTests {
@Autowired
private RedisUtils redisUtils;
@Test
public void contextLoads() {
List list = new ArrayList<>();
list.add("2333");
list.add("test1");
this.redisUtils.set("哈哈哈", list, 12);
System.out.println("---------------------------------");
List result = this.redisUtils.get("哈哈哈", List.class, 11);
System.out.println(result);
}
}
控制台
---------------------------------
null
观察redis数据库:
然后再执行以下代码:
@RunWith(SpringRunner.class)
@SpringBootTest
public class XquantTestApplicationTests {
@Autowired
private RedisUtils redisUtils;
@Test
public void contextLoads() {
List list = new ArrayList<>();
list.add("2333");
list.add("test1");
this.redisUtils.set("哈哈哈", list, 11);
System.out.println("---------------------------------");
List result = this.redisUtils.get("哈哈哈", List.class, 12);
System.out.println(result);
}
}
控制台
---------------------------------
[2333, test1]
观察redis数据库
测试没有问题
可能redis切库在日常业务中用到的地方不多,但是我碰巧遇到了这样的需求,而且在和同事一起研究了一下,他研究RedisTemplate,我研究Jedis,最后发现两种方法都可以实现,故在此记录一下。至于其中的性能差别,或者链接健康情况,还没来得及测试和讨论。
参照:
https://www.jianshu.com/p/9d78cd1c46b6
https://blog.csdn.net/zhongzunfa/article/details/81367355#commentBox?tdsourcetag=s_pctim_aiomsg
https://blog.csdn.net/H971029/article/details/81671916?tdsourcetag=s_pctim_aiomsg