Springboot整合redis切庫問題
切庫問題
由於工作業務需求,需要在單機redis中做切庫處理。一般來說,redis資料庫有16個數據庫,而且有對應的索引,分別為0-15,如下圖 目前的專案時Springboot2.0.5搭建的,當前已經有一個redis工具類了。但是不滿足需求,需要修改。
舊版RedisUtils
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<String, Object> redisTemplate() { RedisTemplate<String, Object> 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<String, String, Object> hashOperations(RedisTemplate<String, Object> redisTemplate) { return redisTemplate.opsForHash(); } @Bean public ValueOperations<String, String> valueOperations(RedisTemplate<String, String> redisTemplate) { return redisTemplate.opsForValue(); } @Bean public ListOperations<String, Object> listOperations(RedisTemplate<String, Object> redisTemplate) { return redisTemplate.opsForList(); } @Bean public SetOperations<String, Object> setOperations(RedisTemplate<String, Object> redisTemplate) { return redisTemplate.opsForSet(); } @Bean public ZSetOperations<String, Object> zSetOperations(RedisTemplate<String, Object> redisTemplate) { return redisTemplate.opsForZSet(); }
RedisUtils
@Component public class RedisUtils { @Autowired private RedisTemplate<String, Object> redisTemplate; @Resource(name="redisTemplate") private ValueOperations<String, String> valueOperations; @Resource(name="redisTemplate") private HashOperations<String, String, Object> hashOperations; @Resource(name="redisTemplate") private ListOperations<String, Object> listOperations; @Resource(name="redisTemplate") private SetOperations<String, Object> setOperations; @Resource(name="redisTemplate") private ZSetOperations<String, Object> 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> T get(String key, Class<T> 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> T get(String key, Class<T> 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> T fromJson(String json, Class<T> 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)
大概意思就是在共享連結情況下不能切換庫。
方案一,還是用RedisTemplate
同事在網上找到了一篇這個文章: Spring cloud 和 Spring Boot 升級到F版和2.x遇到的問題。 這裡面有提到遇到上面那個問題: 給出的解決方案是在例項化RedisTemplate時,不再注入RedisConnectionFactory,改為注入LettuceConnectionFactory ,並關閉共享連結。所以修改當前的redis配置和工具類: 修改後的Redis配置
@Configuration
public class RedisConfig {
@Autowired
private LettuceConnectionFactory factory;
@Bean
public RedisTemplate<String, Object> redisTemplate() {
// 關閉共享連結
factory.setShareNativeConnection(false);
RedisTemplate<String, Object> 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<String, String, Object> hashOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForHash();
}
@Bean
public ValueOperations<String, String> valueOperations(RedisTemplate<String, String> redisTemplate) {
return redisTemplate.opsForValue();
}
@Bean
public ListOperations<String, Object> listOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForList();
}
@Bean
public SetOperations<String, Object> setOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForSet();
}
@Bean
public ZSetOperations<String, Object> zSetOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForZSet();
}
主要修改了兩個地方,注入LettuceConnectionFactory ,關閉共享連結 修改後的RedisUtils
/**
* Redis工具類
*
* 封裝了物件和字串的存,取,刪除,設定過期時間操作. 所有操作可以指定資料庫索引. 存,取可以設定過期時間. 沒有設定預設過期時間,存值時儘量設定過期時間
*
* @author chunhui.tan
* @version 建立時間:2018年10月8日 下午3:31:00
*/
@Component
public class RedisUtils {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Autowired
private ValueOperations<String, String> valueOperations;
@Autowired
private HashOperations<String, String, Object> hashOperations;
@Autowired
private ListOperations<String, Object> listOperations;
@Autowired
private SetOperations<String, Object> setOperations;
@Autowired
private ZSetOperations<String, Object> 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<String, Object> 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> T get(String key, Class<T> 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> T get(String key, Class<T> clazz, Integer dbIndex) {
return get(key, clazz, dbIndex, NOT_EXPIRE);
}
/**
* 取值-物件
*
* @param key 鍵
* @param clazz 位元組碼物件
* @return
*/
public <T> T get(String key, Class<T> 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> T fromJson(String json, Class<T> 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);
}
主要修改的了部分方法的引數,增加資料庫選擇。同事增加了選擇資料庫方法。
測試1
@RunWith(SpringRunner.class)
@SpringBootTest
public class XquantXcrmsApplicationTests {
@Autowired
private RedisUtils redisUtils;
@Test
public void contextLoads() {
List<String> list = new ArrayList<>();
list.add("2333");
list.add("test1");
this.redisUtils.set("哈哈哈", list, 11);
System.out.println(redisUtils.getRedisTemplate().getConnectionFactory().getConnection());
List<String> 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.springf[email protected]b01cb8d
org.[email protected]38c460e8
---------------------------------
org.springf[email protected]b01cb8d
org.[email protected]4e67cfe1
null
修改測試程式碼如下
@RunWith(SpringRunner.class)
@SpringBootTest
public class XquantXcrmsApplicationTests {
@Autowired
private RedisUtils redisUtils;
@Test
public void contextLoads() {
List<String> 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<String> 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.springf[email protected]685d7ba5
org.[email protected]16d41725
---------------------------------
org.springf[email protected]685d7ba5
org.[email protected]4df7d9ee
[2333, test1]
觀察redis客戶端 測試沒有問題
方案二,用Jedis來實現
實際上用原生的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> T get(String key, Class<T> 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> T get(String key, Class<T> clazz, Integer dbIndex) {
return get(key, clazz, dbIndex, NOT_EXPIRE);
}
/**
* 取值-物件
*
* @param key 鍵
* @param clazz 位元組碼物件
* @return
*/
public <T> T get(String key, Class<T> 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> T fromJson(String json, Class<T> 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物件時,指定一下資料庫即可
測試2
情況redis,然後執行以下程式碼
@RunWith(SpringRunner.class)
@SpringBootTest
public class XquantTestApplicationTests {
@Autowired
private RedisUtils redisUtils;
@Test
public void contextLoads() {
List<String> list = new ArrayList<>();
list.add("2333");
list.add("test1");
this.redisUtils.set("哈哈哈", list, 12);
System.out.println("---------------------------------");
List<String> 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<String> list = new ArrayList<>();
list.add("2333");
list.add("test1");
this.redisUtils.set("哈哈哈", list, 11);
System.out.println("---------------------------------");
List<String> result = this.redisUtils.get("哈哈哈", List.class, 12);
System.out.println(result);
}
}
控制檯
---------------------------------
[2333, test1]
觀察redis資料庫 測試沒有問題
總結
可能redis切庫在日常業務中用到的地方不多,但是我碰巧遇到了這樣的需求,而且在和同事一起研究了一下,他研究RedisTemplate,我研究Jedis,最後發現兩種方法都可以實現,故在此記錄一下。至於其中的效能差別,或者連結健康情況,還沒來得及測試和討論。