四、Springboot學習3-整合redis-2018-11-14
阿新 • • 發佈:2018-11-27
1. redis依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
2. 新增配置檔案
# redis相關 # Redis資料庫索引(預設為0) spring.redis.database=0 # Redis伺服器地址 spring.redis.host=127.0.0.1 # Redis伺服器連線埠 spring.redis.port=6379 # Redis伺服器連線密碼(預設為空) spring.redis.password= # 連線池最大連線數(使用負值表示沒有限制) spring.redis.jedis.pool.max-active=8 # 連線池最大阻塞等待時間(使用負值表示沒有限制) spring.redis.jedis.pool.max-wait=-1 # 連線池中的最大空閒連線 spring.redis.jedis.pool.max-idle=8 # 連線池中的最小空閒連線 spring.redis.jedis.pool.min-idle=0 # 連線超時時間(毫秒) spring.redis.timeout=2000
3. 引入redis操作工具類
/** * Created with IntelliJ IDEA. * User: Apollo kh * Date: 2018/11/11. * Time: 上午 12:51. * Explain: Redis的工具類 * 增刪改 -不能在這裡面抓取異常 -因為可能有事務處理 */ @Component public class RedisManager{ public Logger logger= LoggerFactory.getLogger(RedisManager.class); @Autowired protected RedisTemplate redisTemplate; @Autowired protected StringRedisTemplate stringRedisTemplate; @Bean public RedisTemplate<String, Object> stringSerializerRedisTemplate() { RedisSerializer<String> stringSerializer = new StringRedisSerializer(); redisTemplate.setKeySerializer(stringSerializer); redisTemplate.setValueSerializer(stringSerializer); redisTemplate.setHashKeySerializer(stringSerializer); redisTemplate.setHashValueSerializer(stringSerializer); return redisTemplate; } /** * 放值 * @param key * @param value */ public void setKey(String key,String value){ ValueOperations<String, String> ops = stringRedisTemplate.opsForValue(); ops.set(key,value,1, TimeUnit.MINUTES);//1分鐘過期 } /** * 取值 * @param key * @return */ public String getValue(String key){ ValueOperations<String, String> ops = stringRedisTemplate.opsForValue(); return ops.get(key); } /** * 出異常,重複操作的次數 */ private Integer times = 5; /** * 使用者排序通過註冊時間的 權重值 * @param date * @return */ public double getCreateTimeScore(long date) { return date/ 100000.0; } /** * 獲取Redis中所有的鍵的key * @return */ public Set<String> getAllKeys() { return redisTemplate.keys("*"); } /** * 獲取所有的普通key-value * @return */ public Map<String, Object> getAllString() { Set<String> stringSet = getAllKeys(); Map<String, Object> map = new HashMap<String, Object>(); Iterator<String> iterator = stringSet.iterator(); while (iterator.hasNext()) { String k = iterator.next(); if (getType(k) == DataType.STRING) { map.put(k, get(k)); } } return map; } /** * 獲取所有的Set -key-value * @return */ public Map<String, Set<Object>> getAllSet() { Set<String> stringSet = getAllKeys(); Map<String, Set<Object>> map = new HashMap<String, Set<Object>>(); Iterator<String> iterator = stringSet.iterator(); while (iterator.hasNext()) { String k = iterator.next(); if (getType(k) == DataType.SET) { map.put(k, getSet(k)); } } return map; } /** * 獲取所有的ZSet倒序 -key-value 不獲取權重值 * @return */ public Map<String, Set<Object>> getAllZSetRange() { Set<String> stringSet = getAllKeys(); Map<String, Set<Object>> map = new HashMap<String, Set<Object>>(); Iterator<String> iterator = stringSet.iterator(); while (iterator.hasNext()) { String k = iterator.next(); if (getType(k) == DataType.ZSET) { logger.debug("k:"+k); map.put(k, getZSetRange(k)); } } return map; } /** * 獲取所有的ZSet正序 -key-value 不獲取權重值 * @return */ public Map<String, Set<Object>> getAllZSetReverseRange() { Set<String> stringSet = getAllKeys(); Map<String, Set<Object>> map = new HashMap<String, Set<Object>>(); Iterator<String> iterator = stringSet.iterator(); while (iterator.hasNext()) { String k = iterator.next(); if (getType(k) == DataType.ZSET) { map.put(k, getZSetReverseRange(k)); } } return map; } /** * 獲取所有的List -key-value * @return */ public Map<String, List<Object>> getAllList() { Set<String> stringSet = getAllKeys(); Map<String, List<Object>> map = new HashMap<String, List<Object>>(); Iterator<String> iterator = stringSet.iterator(); while (iterator.hasNext()) { String k = iterator.next(); if (getType(k) == DataType.LIST) { map.put(k, getList(k)); } } return map; } /** * 獲取所有的Map -key-value * @return */ public Map<String, Map<String, Object>> getAllMap() { Set<String> stringSet = getAllKeys(); Map<String, Map<String, Object>> map = new HashMap<String, Map<String, Object>>(); Iterator<String> iterator = stringSet.iterator(); while (iterator.hasNext()) { String k = iterator.next(); if (getType(k) == DataType.HASH) { map.put(k, getMap(k)); } } return map; } /** * 新增一個list * @param key * @param objectList */ public void addList(String key, List<Object> objectList) { for (Object obj : objectList) { addList(key, obj); } } /** * 向list中增加值 * @param key * @param obj * @return 返回在list中的下標 */ public long addList(String key, Object obj) { return redisTemplate.boundListOps(key).rightPush(obj); } /** * * 向list中增加值 * @param key * @param obj * @return 返回在list中的下標 */ public long addList(String key, Object... obj) { return redisTemplate.boundListOps(key).rightPushAll(obj); } /** * * 輸出list * @param key List的key * @param s 開始下標 * @param e 結束的下標 * @return */ public List<Object> getList(String key, long s, long e) { return redisTemplate.boundListOps(key).range(s, e); } /** * 輸出完整的list * @param key */ public List<Object> getList(String key) { return redisTemplate.boundListOps(key).range(0, getListSize(key)); } /** * 獲取list集合中元素的個數 * @param key * @return */ public long getListSize(String key) { return redisTemplate.boundListOps(key).size(); } /** * 移除list中某值 * 移除list中 count個value為object的值,並且返回移除的數量, * 如果count為0,或者大於list中為value為object數量的總和, * 那麼移除所有value為object的值,並且返回移除數量 * @param key * @param object * @return 返回移除數量 */ public long removeListValue(String key, Object object) { return redisTemplate.boundListOps(key).remove(0, object); } /** * 移除list中某值 * @param key * @param object * @return 返回移除數量 */ public long removeListValue(String key, Object... objects) { long r = 0; for (Object object : objects) { r += removeListValue(key, object); } return r; } /** * 批量刪除key對應的value * @param keys */ public void remove(String... key) { if (key != null && key.length > 0) { if (key.length == 1) { remove(key[0]); } else { redisTemplate.delete(CollectionUtils.arrayToList(key)); } } } /** * 模糊移除 支援*號等匹配移除 * @param blears */ public void removeBlear(String... blears) { for (String blear : blears) { removeBlear(blear); } } /** * 修改key名 如果不存在該key或者沒有修改成功返回false * @param oldKey * @param newKey * @return */ public Boolean renameIfAbsent(String oldKey, String newKey) { return redisTemplate.renameIfAbsent(oldKey, newKey); } /** * 模糊移除 支援*號等匹配移除 * @param blear */ public void removeBlear(String blear) { redisTemplate.delete(redisTemplate.keys(blear)); } /** * 根據正則表示式來移除key-value * @param blears */ public void removeByRegular(String... blears) { for (String blear : blears) { removeBlear(blear); } } /** * 根據正則表示式來移除key-value * @param blears */ public void removeByRegular(String blear) { Set<String> stringSet = getAllKeys(); for (String s : stringSet) { if (Pattern.compile(blear).matcher(s).matches()) { redisTemplate.delete(s); } } } /** * 根據正則表示式來移除 Map中的key-value * @param key * @param blears */ public void removeMapFieldByRegular(String key, String... blears) { for (String blear : blears) { removeMapFieldByRegular(key, blear); } } /** * 根據正則表示式來移除 Map中的key-value * @param key * @param blear */ public void removeMapFieldByRegular(String key, String blear) { Map<String, Object> map = getMap(key); Set<String> stringSet = map.keySet(); for (String s : stringSet) { if (Pattern.compile(blear).matcher(s).matches()) { redisTemplate.boundHashOps(key).delete(s); } } } /** * 移除key 對應的value * @param key * @param value * @return */ public Long removeZSetValue(String key, Object... value) { return redisTemplate.boundZSetOps(key).remove(value); } /** * 移除key ZSet * @param key * @return */ public void removeZSet(String key) { removeZSetRange(key, 0L, getZSetSize(key)); } /** *刪除,鍵為K的集合,索引start<=index<=end的元素子集 * @param key * @param start * @param end * @return */ public void removeZSetRange(String key, Long start, Long end) { redisTemplate.boundZSetOps(key).removeRange(start, end); } /** * 並集 將key對應的集合和key1對應的集合合併到key2中 * 如果分數相同的值,都會保留 * 原來key2的值會被覆蓋 * @param key * @param key1 * @param key2 */ public void setZSetUnionAndStore(String key,String key1, String key2) { redisTemplate.boundZSetOps(key).unionAndStore(key1,key2); } /** * 獲取整個有序集合ZSET,正序 * @param key */ public Set<Object> getZSetRange(String key) { return getZSetRange(key, 0, getZSetSize(key)); } /** * 獲取有序集合ZSET * 鍵為K的集合,索引start<=index<=end的元素子集,正序 * @param key * @param start 開始位置 * @param end 結束位置 */ public Set<Object> getZSetRange(String key, long s, long e) { return redisTemplate.boundZSetOps(key).range(s, e); } /** * 獲取整個有序集合ZSET,倒序 * @param key */ public Set<Object> getZSetReverseRange(String key) { return getZSetReverseRange(key, 0, getZSetSize(key)); } /** * 獲取有序集合ZSET * 鍵為K的集合,索引start<=index<=end的元素子集,倒序 * @param key * @param start 開始位置 * @param end 結束位置 */ public Set<Object> getZSetReverseRange(String key, long start, long end) { return redisTemplate.boundZSetOps(key).reverseRange(start, end); } /** * 通過分數(權值)獲取ZSET集合 正序 -從小到大 * @param key * @param start * @param end * @return */ public Set<Object> getZSetRangeByScore(String key, double start, double end) { return redisTemplate.boundZSetOps(key).rangeByScore(start, end); } /** * 通過分數(權值)獲取ZSET集合 倒序 -從大到小 * @param key * @param start * @param end * @return */ public Set<Object> getZSetReverseRangeByScore(String key, double start, double end) { return redisTemplate.boundZSetOps(key).reverseRangeByScore(start, end); } /** * 鍵為K的集合,索引start<=index<=end的元素子集 * 返回泛型介面(包括score和value),正序 * @param key * @param start * @param end * @return */ public Set<ZSetOperations.TypedTuple<Object>> getZSetRangeWithScores(String key, long start, long end) { return redisTemplate.boundZSetOps(key).rangeWithScores(start, end); } /** * 鍵為K的集合,索引start<=index<=end的元素子集 * 返回泛型介面(包括score和value),倒序 * @param key * @param start * @param end * @return */ public Set<ZSetOperations.TypedTuple<Object>> getZSetReverseRangeWithScores(String key, long start, long end) { return redisTemplate.boundZSetOps(key).reverseRangeWithScores(start, end); } /** * 鍵為K的集合 * 返回泛型介面(包括score和value),正序 * @param key * @return */ public Set<ZSetOperations.TypedTuple<Object>> getZSetRangeWithScores(String key) { return getZSetRangeWithScores(key, 0, getZSetSize(key)); } /** * 鍵為K的集合 * 返回泛型介面(包括score和value),倒序 * @param key * @return */ public Set<ZSetOperations.TypedTuple<Object>> getZSetReverseRangeWithScores(String key) { return getZSetReverseRangeWithScores(key, 0, getZSetSize(key)); } /** * 鍵為K的集合,sMin<=score<=sMax的元素個數 * @param key * @param sMin * @param sMax * @return */ public long getZSetCountSize(String key, double sMin, double sMax) { return redisTemplate.boundZSetOps(key).count(sMin, sMax); } /** * 獲取Zset 鍵為K的集合元素個數 * @param key * @return */ public long getZSetSize(String key) { return redisTemplate.boundZSetOps(key).size(); } /** * 獲取鍵為K的集合,value為obj的元素分數 * @param key * @param value * @return */ public double getZSetScore(String key, Object value) { return redisTemplate.boundZSetOps(key).score(value); } /** * 元素分數增加,delta是增量 * @param key * @param value * @param delta * @return */ public double incrementZSetScore(String key, Object value, double delta) { return redisTemplate.boundZSetOps(key).incrementScore(value, delta); } /** * 新增有序集合ZSET * 預設按照score升序排列,儲存格式K(1)==V(n),V(1)=S(1) * @param key * @param score * @param value * @return */ public Boolean addZSet(String key, double score, Object value) { return redisTemplate.boundZSetOps(key).add(value, score); } /** * 新增有序集合ZSET * @param key * @param value * @return */ public Long addZSet(String key, TreeSet<Object> value) { return redisTemplate.boundZSetOps(key).add(value); } /** * 新增有序集合ZSET * @param key * @param score * @param value * @return */ public Boolean addZSet(String key, double[] score, Object[] value) { if (score.length != value.length) { return false; } for (int i = 0; i < score.length; i++) { if (addZSet(key, score[i], value[i]) == false) { return false; } } return true; } /** * 刪除快取 * 根據key精確匹配刪除 * @param key */ public void remove(String key) { if (exists(key)) { redisTemplate.delete(key); } } /** * 通過分數刪除ZSet中的值 * @param key * @param s * @param e */ public void removeZSetRangeByScore(String key,double s , double e) { redisTemplate.boundZSetOps(key).removeRangeByScore(s,e); } /** * 設定Set的過期時間 * @param key * @param time * @return */ public Boolean setSetExpireTime(String key, Long time) { return redisTemplate.boundSetOps(key).expire(time, TimeUnit.SECONDS); } /** * 設定ZSet的過期時間 * @param key * @param time * @return */ public Boolean setZSetExpireTime(String key, Long time) { return redisTemplate.boundZSetOps(key).expire(time, TimeUnit.SECONDS); } /** * 判斷快取中是否有key對應的value * @param key * @return */ public boolean exists(String key) { return redisTemplate.hasKey(key); } /** * 讀取String快取 可以是物件 * @param key * @return */ public Object get(String key) { return redisTemplate.boundValueOps(key).get(); } /** * 讀取String快取 可以是物件 * @param key * @return */ public List<Object> get(String... keys) { List<Object> list = new ArrayList<Object>(); for (String key : keys) { list.add(get(key)); } return list; } /** * 讀取快取 可以是物件 根據正則表示式匹配 * @param regKey * @return */ public List<Object> getByRegular(String regKey) { Set<String> stringSet = getAllKeys(); List<Object> objectList = new ArrayList<Object>(); for (String s : stringSet) { if (Pattern.compile(regKey).matcher(s).matches() && getType(s) == DataType.STRING) { objectList.add(get(s)); } } return objectList; } /** * 寫入快取 可以是物件 * @param key * @param value */ public void set(String key, Object value) { redisTemplate.boundValueOps(key).set(value); } /** * 寫入快取 * @param key * @param value * @param expireTime 過期時間 -單位s * @return */ public void set(String key, Object value, Long expireTime) { redisTemplate.boundValueOps(key).set(value, expireTime, TimeUnit.SECONDS); } /** * 設定一個key的過期時間(單位:秒) * @param key * @param expireTime * @return */ public boolean setExpireTime(String key, Long expireTime) { return redisTemplate.expire(key, expireTime, TimeUnit.SECONDS); } /** * 獲取key的型別 * @param key * @return */ public DataType getType(String key) { return redisTemplate.type(key); } /** * 刪除map中的某個物件 * @param key map對應的key * @param field map中該物件的key */ public void removeMapField(String key, Object... field) { redisTemplate.boundHashOps(key).delete(field); } /** * 獲取map物件 * @param key map對應的key * @return */ public Long getMapSize(String key) { return redisTemplate.boundHashOps(key).size(); } /** * 獲取map物件 * @param key map對應的key * @return */ public Map<String, Object> getMap(String key) { return redisTemplate.boundHashOps(key).entries(); } /** * 獲取map快取中的某個物件 * @param key map對應的key * @param field map中該物件的key * @return */ public <T> T getMapField(String key, String field) { return (T) redisTemplate.boundHashOps(key).get(field); } /** * 判斷map中對應key的key是否存在 * @param key map對應的key * @return */ public Boolean hasMapKey(String key, String field) { return redisTemplate.boundHashOps(key).hasKey(field); } /** * 獲取map對應key的value * @param key map對應的key * @return */ public List<Object> getMapFieldValue(String key) { return redisTemplate.boundHashOps(key).values(); } /** * 獲取map的key * @param key map對應的key * @return */ public Set<Object> getMapFieldKey(String key) { return redisTemplate.boundHashOps(key).keys(); } /** * 新增map * @param key * @param map */ public void addMap(String key, Map<String, Object> map) { redisTemplate.boundHashOps(key).putAll(map); } /** * 向key對應的map中新增快取物件 * @param key cache物件key * @param field map對應的key * @param value 值 */ public void addMap(String key, String field, Object value) { redisTemplate.boundHashOps(key).put(field, value); } /** * 向key對應的map中新增快取物件 * @param key cache物件key * @param field map對應的key * @param time 過期時間-整個MAP的過期時間 * @param value 值 */ public void addMap(String key, String field, Object value, long time) { redisTemplate.boundHashOps(key).put(field, value); redisTemplate.boundHashOps(key).expire(time, TimeUnit.SECONDS); } /** * 處理事務時鎖定key * @param key */ public void watch(String key) { redisTemplate.watch(key); } /** * 向set中加入物件 * @param key 物件key * @param obj 值 */ public void addSet(String key, Object... obj) { redisTemplate.boundSetOps(key).add(obj); } /** * 移除set中的某些值 * @param key 物件key * @param obj 值 */ public long removeSetValue(String key, Object obj) { return redisTemplate.boundSetOps(key).remove(obj); } /** * 移除set中的某些值 * @param key 物件key * @param obj 值 */ public long removeSetValue(String key, Object... obj) { if (obj != null && obj.length > 0) { return redisTemplate.boundSetOps(key).remove(obj); } return 0L; } /** * 獲取set的物件數 * @param key 物件key */ public long getSetSize(String key) { return redisTemplate.boundSetOps(key).size(); } /** * 判斷set中是否存在這個值 * @param key 物件key */ public Boolean hasSetValue(String key, Object obj) { Boolean boo = null; int t =0; while (true){ try { boo = redisTemplate.boundSetOps(key).isMember(obj); break; } catch (Exception e) { logger.error("key[" + key + "],obj[" + obj + "]判斷Set中的值是否存在失敗,異常資訊:" + e.getMessage()); t++; } if(t>times){ break; } } logger.info("key[" + key + "],obj[" + obj + "]是否存在,boo:" + boo); return boo; } /** * 獲得整個set * @param key 物件key */ public Set<Object> getSet(String key) { return redisTemplate.boundSetOps(key).members(); } /** * 獲得set 並集 * @param key * @param otherKey * @return */ public Set<Object> getSetUnion(String key, String otherKey) { return redisTemplate.boundSetOps(key).union(otherKey); } /** * 獲得set 並集 * @param key * @param set * @return */ public Set<Object> getSetUnion(String key, Set<Object> set) { return redisTemplate.boundSetOps(key).union(set); } /** * 獲得set 交集 * @param key * @param otherKey * @return */ public Set<Object> getSetIntersect(String key, String otherKey) { return redisTemplate.boundSetOps(key).intersect(otherKey); } /** * 獲得set 交集 * @param key * @param set * @return */ public Set<Object> getSetIntersect(String key, Set<Object> set) { return redisTemplate.boundSetOps(key).intersect(set); } }
4. 進行測試
@RestController public class RedisController { private final static Log log = LogFactory.getLog(LoginController.class); @Autowired RedisManager redisManager; @RequestMapping("/redis") public String index() { redisManager.setKey("kanghu1","IG1"); log.info("key(kanghu) value:"+redisManager.getValue("kanghu1")); redisManager.setKey("kanghu2","IG2"); log.info("key(kanghu) value:"+redisManager.getValue("kanghu2")); Set<String> allKeys = redisManager.getAllKeys(); for (String key: allKeys) { log.info("current key:"+key); } return "redis"; } }