1-添加maven依賴
2-添加redis配置
3-工具類
1-添加maven依賴
實際上是封裝了jedis
<!-- redis 依賴--> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>1.8.7.RELEASE</version> </dependency>
2-添加redis配置
# REDIS (RedisProperties)
# Redis服務器連接密碼(默認為空)
spring.redis.password=
# 連接池最大連接數(使用負值表示沒有限制)
spring.redis.pool.max-active=1024
# 連接池最大阻塞等待時間(使用負值表示沒有限制)
spring.redis.pool.max-wait=10000
# 連接池中的最大空閑連接
spring.redis.pool.max-idle=200
# 連接池中的最小空閑連接
spring.redis.pool.min-idle=50
# 連接超時時間(毫秒)
spring.redis.timeout=10000
#哨兵監聽redies server
spring.redis.sentinel.master=mymaster
#哨兵的配置列表
spring.redis.sentinel.nodes=192.168.2.228:26379,192.168.2.236:26379,192.168.2.237:26379
3-封裝工具類
import org.springframework.dao.DataAccessException; import org.springframework.data.redis.connection.RedisConnection; import org.springframework.data.redis.core.*; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.stereotype.Component; import com.google.gson.Gson; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; import javax.annotation.Resource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.util.StringUtils; /** * Redis工具類 */ @Component public class RedisUtils { private final Logger logger = LoggerFactory.getLogger(this.getClass()); @Autowired private RedisTemplate redisTemplate; @Resource(name = "redisTemplate") private ValueOperations<String, String> valueOperations; /** * 默認過期時長,單位:秒 */ public final static long DEFAULT_EXPIRE = 60 * 60 * 24; /** * 加鎖過期時長,單位:秒 */ public final static long LOCK_EXPIRE = 60 * 60; /** * 不設置過期時長 */ public final static long NOT_EXPIRE = -1; private final static Gson GSON = new Gson(); //=============================common============================ /** * 指定緩存失效時間 * * @param key 鍵 * @param time 時間(秒) */ public boolean expire(CtimsModelEnum modelEnum, String key, long time) { try { if (time > 0) { redisTemplate.expire(formatKey(modelEnum, key), time, TimeUnit.SECONDS); } return true; } catch (Exception e) { logger.error("redis 操作失敗,失敗原因:", e); e.printStackTrace(); return false; } } /** * 根據key 獲取過期時間 * * @param key 鍵 不能為null * @return 時間(秒) 返回0代表為永久有效 */ public long getExpire(CtimsModelEnum modelEnum, String key) { return redisTemplate.getExpire(formatKey(modelEnum, key), TimeUnit.SECONDS); } /** * 判斷key是否存在 * * @param key 鍵 * @return true 存在 false不存在 */ public boolean hasKey(CtimsModelEnum modelEnum, String key) { try { return redisTemplate.hasKey(formatKey(modelEnum, key)); } catch (Exception e) { logger.error("redis 操作失敗,失敗原因:", e); e.printStackTrace(); return false; } } /** * 刪除緩存 * * @param key 可以傳一個值 或多個 */ @SuppressWarnings("unchecked") public void del(CtimsModelEnum modelEnum, String... key) { if (key != null && key.length > 0) { if (key.length == 1) { redisTemplate.delete(formatKey(modelEnum, key[0])); } else { redisTemplate.delete(formatKey(modelEnum, key)); } } } //============================String============================= /** * 普通緩存放入並設置時間 * * @param key 鍵 * @param value 值 * @param expire 時間(秒) time要大於0 如果time小於等於0 將設置無限期 * @return true成功 false 失敗 */ public void set(CtimsModelEnum modelEnum, String key, Object value, long expire) { if(expire != NOT_EXPIRE){ valueOperations.set(formatKey(modelEnum, key), toJson(value),expire,TimeUnit.SECONDS); }else{ valueOperations.set(formatKey(modelEnum, key), toJson(value)); } // if (expire != NOT_EXPIRE) { // redisTemplate.expire(formatKey(modelEnum, key), expire, TimeUnit.SECONDS); // } } /** * 普通緩存放入 * * @param key 鍵 * @param value 值 * @return true成功 false失敗 */ public void set(CtimsModelEnum modelEnum, String key, Object value) { set(modelEnum, key, value, NOT_EXPIRE); } public <T> T get(CtimsModelEnum modelEnum, String key, Class<T> clazz, long expire) { String value = valueOperations.get(formatKey(modelEnum, key)); if (expire != NOT_EXPIRE) { redisTemplate.expire(formatKey(modelEnum, key), expire, TimeUnit.SECONDS); } return value == null ? null : fromJson(value, clazz); } /** * 普通Model緩存獲取 * * @param key 鍵,clazz * @return T 值 */ public <T> T get(CtimsModelEnum modelEnum, String key, Class<T> clazz) { return get(modelEnum, key, clazz, NOT_EXPIRE); } /** * 普通string緩存獲取 * * @param key 鍵,expire 更新緩存失效時間 * @return T 值 */ public String get(CtimsModelEnum modelEnum, String key, long expire) { String value = valueOperations.get(formatKey(modelEnum, key)); if (expire != NOT_EXPIRE) { redisTemplate.expire(formatKey(modelEnum, key), expire, TimeUnit.SECONDS); } return value; } /** * 普通緩存獲取 * * @param key 鍵,clazz * @return string 值 */ public String get(CtimsModelEnum modelEnum, String key) { return get(modelEnum, key, NOT_EXPIRE); } /** * 遞增 * * @param key 鍵 * @param delta 要增加幾(大於0) */ public long incr(CtimsModelEnum modelEnum, String key, long delta) { if (delta < 0) { throw new RuntimeException("遞增因子必須大於0"); } return redisTemplate.opsForValue().increment(formatKey(modelEnum, key), delta); } /** * 遞減 * * @param key 鍵 * @param delta 要減少幾(小於0) */ public long decr(CtimsModelEnum modelEnum, String key, long delta) { if (delta < 0) { throw new RuntimeException("遞減因子必須大於0"); } return redisTemplate.opsForValue().increment(formatKey(modelEnum, key), -delta); } //================================Map================================= /** * HashGet * * @param key 鍵 不能為null * @param item 項 不能為null * @return 值 */ public Object hget(CtimsModelEnum modelEnum, String key, String item) { return redisTemplate.opsForHash().get(formatKey(modelEnum, key), item); } /** * HashGet * * @param key 鍵 不能為null * @param item 項 不能為null * @return 值 */ public <T> T hget(CtimsModelEnum modelEnum, String key, String item, Class<T> clazz) { String value = (String) redisTemplate.opsForHash().get(formatKey(modelEnum, key), item); return value == null ? null : fromJson(value, clazz); } /** * 獲取hashKey對應的所有鍵值 * * @param key 鍵 * @return 對應的多個鍵值 */ public Map<Object, Object> hmget(CtimsModelEnum modelEnum, String key) { return redisTemplate.opsForHash().entries(formatKey(modelEnum, key)); } /** * HashSet * * @param key 鍵 * @param map 對應多個鍵值 * @return true 成功 false 失敗 */ public boolean hmset(CtimsModelEnum modelEnum, String key, Map<String, Object> map) { try { redisTemplate.opsForHash().putAll(formatKey(modelEnum, key), map); return true; } catch (Exception e) { logger.error("redis 操作失敗,失敗原因:", e); e.printStackTrace(); return false; } } /** * HashSet 並設置時間 * * @param key 鍵 * @param map 對應多個鍵值 * @param time 時間(秒) * @return true成功 false失敗 */ public boolean hmset(CtimsModelEnum modelEnum, String key, Map<String, Object> map, long time) { try { redisTemplate.opsForHash().putAll(formatKey(modelEnum, key), map); if (time > 0) { expire(modelEnum, key, time); } return true; } catch (Exception e) { logger.error("redis 操作失敗,失敗原因:", e); e.printStackTrace(); return false; } } /** * 向一張hash表中放入數據,如果不存在將創建 * * @param key 鍵 * @param item 項 * @param value 值 * @return true 成功 false失敗 */ public boolean hset(CtimsModelEnum modelEnum, String key, String item, Object value) { try { int cs = 1; // 向Redis中入數據的次數 while(true){ redisTemplate.opsForHash().put(formatKey(modelEnum, key), item, value); if(cs > 3 || hasKey(modelEnum, key)){ break; }else{ cs ++; } } if(cs > 3){ throw new Exception("向Redis插入數據失敗,請稍后再試"); } return true; } catch (Exception e) { logger.error("redis 操作失敗,失敗原因:", e); e.printStackTrace(); return false; } } /** * 向一張hash表中放入數據,如果不存在將創建 * 並指定緩存失效時間 * * @param key 鍵 * @param item 項 * @param value 值 * @param time 時間(秒) 注意:如果已存在的hash表有時間,這里將會替換原有的時間 * @return true 成功 false失敗 */ public boolean hset(CtimsModelEnum modelEnum, String key, String item, Object value, long time) { try { int cs = 1; // 向Redis中入數據的次數 while(true){ redisTemplate.opsForHash().put(formatKey(modelEnum, key), item, value); // 如果緩存失效時間大於0,則指定緩存失效時間 if (time > 0) { expire(modelEnum, key, time); } if(cs > 3 || hasKey(modelEnum, key)){ break; }else{ cs ++; } } if(cs > 3){ throw new Exception("向Redis插入數據失敗,請稍后再試"); } return true; } catch (Exception e) { logger.error("redis 操作失敗,失敗原因:", e); e.printStackTrace(); return false; } } /** * 刪除hash表中的值 * * @param key 鍵 不能為null * @param item 項 可以使多個 不能為null */ public void hdel(CtimsModelEnum modelEnum, String key, Object... item) { redisTemplate.opsForHash().delete(formatKey(modelEnum, key), item); } /** * 判斷hash表中是否有該項的值 * * @param key 鍵 不能為null * @param item 項 不能為null * @return true 存在 false不存在 */ public boolean hHasKey(CtimsModelEnum modelEnum, String key, String item) { return redisTemplate.opsForHash().hasKey(formatKey(modelEnum, key), item); } /** * hash遞增 如果不存在,就會創建一個 並把新增后的值返回 * * @param key 鍵 * @param item 項 * @param by 要增加幾(大於0) */ public double hincr(CtimsModelEnum modelEnum, String key, String item, double by) { return redisTemplate.opsForHash().increment(formatKey(modelEnum, key), item, by); } /** * hash遞減 * * @param key 鍵 * @param item 項 * @param by 要減少記(小於0) */ public double hdecr(CtimsModelEnum modelEnum, String key, String item, double by) { return redisTemplate.opsForHash().increment(formatKey(modelEnum, key), item, -by); } //============================set============================= /** * 根據key獲取Set中的所有值 * * @param key 鍵 */ public Set<Object> sGet(CtimsModelEnum modelEnum, String key) { try { return redisTemplate.opsForSet().members(formatKey(modelEnum, key)); } catch (Exception e) { logger.error("redis 操作失敗,失敗原因:", e); e.printStackTrace(); return null; } } /** * 根據value從一個set中查詢,是否存在 * * @param key 鍵 * @param value 值 * @return true 存在 false不存在 */ public boolean sHasKey(CtimsModelEnum modelEnum, String key, Object value) { try { return redisTemplate.opsForSet().isMember(formatKey(modelEnum, key), value); } catch (Exception e) { logger.error("redis 操作失敗,失敗原因:", e); e.printStackTrace(); return false; } } /** * 將數據放入set緩存 * * @param key 鍵 * @param values 值 可以是多個 * @return 成功個數 */ public long sSet(CtimsModelEnum modelEnum, String key, Object... values) { try { return redisTemplate.opsForSet().add(formatKey(modelEnum, key), values); } catch (Exception e) { logger.error("redis 操作失敗,失敗原因:", e); e.printStackTrace(); return 0; } } /** * 將set數據放入緩存 * * @param key 鍵 * @param time 時間(秒) * @param values 值 可以是多個 * @return 成功個數 */ public long sSetAndTime(CtimsModelEnum modelEnum, String key, long time, Object... values) { try { Long count = redisTemplate.opsForSet().add(formatKey(modelEnum, key), values); if (time > 0) { expire(modelEnum, key, time); } return count; } catch (Exception e) { logger.error("redis 操作失敗,失敗原因:", e); e.printStackTrace(); return 0; } } /** * 獲取set緩存的長度 * * @param key 鍵 */ public long sGetSetSize(CtimsModelEnum modelEnum, String key) { try { return redisTemplate.opsForSet().size(formatKey(modelEnum, key)); } catch (Exception e) { logger.error("redis 操作失敗,失敗原因:", e); e.printStackTrace(); return 0; } } /** * 移除值為value的 * * @param key 鍵 * @param values 值 可以是多個 * @return 移除的個數 */ public long setRemove(CtimsModelEnum modelEnum, String key, Object... values) { try { Long count = redisTemplate.opsForSet().remove(formatKey(modelEnum, key), values); return count; } catch (Exception e) { logger.error("redis 操作失敗,失敗原因:", e); e.printStackTrace(); return 0; } } //===============================list================================= /** * 獲取list緩存的內容 * * @param key 鍵 * @param start 開始 * @param end 結束 0 到 -1代表所有值 */ public List<Object> lGet(CtimsModelEnum modelEnum, String key, long start, long end) { try { return redisTemplate.opsForList().range(formatKey(modelEnum, key), start, end); } catch (Exception e) { logger.error("redis 操作失敗,失敗原因:", e); e.printStackTrace(); return null; } } /** * 獲取list緩存的長度 * * @param key 鍵 */ public long lGetListSize(CtimsModelEnum modelEnum, String key) { try { return redisTemplate.opsForList().size(formatKey(modelEnum, key)); } catch (Exception e) { logger.error("redis 操作失敗,失敗原因:", e); e.printStackTrace(); return 0; } } /** * 通過索引 獲取list中的值 * * @param key 鍵 * @param index 索引 index>=0時, 0 表頭,1 第二個元素,依次類推;index<0時,-1,表尾,-2倒數第二個元素,依次類推 */ public Object lGetIndex(CtimsModelEnum modelEnum, String key, long index) { try { return redisTemplate.opsForList().index(formatKey(modelEnum, key), index); } catch (Exception e) { logger.error("redis 操作失敗,失敗原因:", e); e.printStackTrace(); return null; } } /** * 將list放入緩存 * * @param key 鍵 * @param value 值 */ public boolean lSet(CtimsModelEnum modelEnum, String key, Object value) { try { redisTemplate.opsForList().rightPush(formatKey(modelEnum, key), value); return true; } catch (Exception e) { logger.error("redis 操作失敗,失敗原因:", e); e.printStackTrace(); return false; } } /** * 將list放入緩存 * * @param key 鍵 * @param value 值 * @param time 時間(秒) */ public boolean lSet(CtimsModelEnum modelEnum, String key, Object value, long time) { try { redisTemplate.opsForList().rightPush(formatKey(modelEnum, key), value); if (time > 0) { expire(modelEnum, key, time); } return true; } catch (Exception e) { logger.error("redis 操作失敗,失敗原因:", e); e.printStackTrace(); return false; } } /** * 將list放入緩存 * * @param key 鍵 * @param value 值 */ public boolean lSet(CtimsModelEnum modelEnum, String key, List<Object> value) { try { redisTemplate.opsForList().rightPushAll(formatKey(modelEnum, key), value); return true; } catch (Exception e) { logger.error("redis 操作失敗,失敗原因:", e); e.printStackTrace(); return false; } } /** * 將list放入緩存 * * @param key 鍵 * @param value 值 * @param time 時間(秒) */ public boolean lSet(CtimsModelEnum modelEnum, String key, List<Object> value, long time) { try { redisTemplate.opsForList().rightPushAll(formatKey(modelEnum, key), value); if (time > 0) { expire(modelEnum, key, time); } return true; } catch (Exception e) { logger.error("redis 操作失敗,失敗原因:", e); e.printStackTrace(); return false; } } /** * 根據索引修改list中的某條數據 * * @param key 鍵 * @param index 索引 * @param value 值 */ public boolean lUpdateIndex(CtimsModelEnum modelEnum, String key, long index, Object value) { try { redisTemplate.opsForList().set(formatKey(modelEnum, key), index, value); return true; } catch (Exception e) { logger.error("redis 操作失敗,失敗原因:", e); e.printStackTrace(); return false; } } /** * 移除N個值為value * * @param key 鍵 * @param count 移除多少個 * @param value 值 * @return 移除的個數 */ public long lRemove(CtimsModelEnum modelEnum, String key, long count, Object value) { try { Long remove = redisTemplate.opsForList() .remove(formatKey(modelEnum, key), count, value); return remove; } catch (Exception e) { logger.error("redis 操作失敗,失敗原因:", e); e.printStackTrace(); return 0; } } /** * 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); } /** * Function: redis關鍵字生成<br/> * * @author luxiangxing<br/> * @date 2018/6/27 下午8:12<br/> * @param<br/> * @return<br/> * @version */ private String formatKey(CtimsModelEnum modelEnum, String key) { return "ctims:" + modelEnum.getCode() + ":" + key; } private List<String> formatKey(CtimsModelEnum modelEnum, String... key) { List<String> list = new ArrayList<>(); for (String k : key) { list.add(formatKey(modelEnum, k)); } return list; } /** * 加鎖 * * @param value 當前時間+超時時間 */ public boolean lock(String key, String value) { //SETNX命令, 可以設置返回true, 不可以返回false if (redisTemplate.opsForValue().setIfAbsent(key, value)) { return true; } String currentValue = (String) redisTemplate.opsForValue().get(key); //如果鎖過期 if (!StringUtils.isEmpty(currentValue) && (Long.parseLong(currentValue) < System.currentTimeMillis())) { //GETSET命令, 獲取上一個鎖的時間 String oldValue = (String) redisTemplate.opsForValue().getAndSet(key, value); if (!StringUtils.isEmpty(oldValue) && oldValue.equals(value)) { return true; } } return false; } /** * 解鎖 */ public void unLock(String key, String value) { try { String currentValue = (String) redisTemplate.opsForValue().get(key); if (!StringUtils.isEmpty(currentValue) && currentValue.equals(value)) { redisTemplate.opsForValue().getOperations().delete(key); } } catch (Exception e) { logger.error("【redis分布式鎖】解鎖異常, {}", e); } } /** * 批量向redis中插入:key value * 如果鍵已存在則返回false,不更新,防止覆蓋。使用pipeline批處理方式(不關注返回值) * @param list 一個map代表一行記錄,2個key:key & value。 * @param ctimsModelEnum redis中key的值前綴。 * @return */ public boolean pipelinedString(final List<Map<String, Object>> list, final CtimsModelEnum ctimsModelEnum) { boolean result = (boolean) redisTemplate.execute(new RedisCallback<Boolean>() { @Override public Boolean doInRedis(RedisConnection connection) throws DataAccessException { RedisSerializer<String> serializer = redisTemplate.getStringSerializer(); for (Map<String, Object> map : list) { byte[] key = serializer .serialize(formatKey(ctimsModelEnum, map.get("key").toString())); byte[] values = serializer.serialize(map.get("value").toString()); connection.set(key, values); } return true; } }, false, true); return result; } /** * 批量向redis中插入:key value * 如果鍵已存在則返回false,不更新,防止覆蓋。使用pipeline批處理方式(不關注返回值) * @param list 一個map代表一行記錄,2個key:key & value。 * @param ctimsModelEnum redis中key的值前綴。 * @return */ public boolean pipelinedHash(final List<Map<String, Object>> list, final CtimsModelEnum ctimsModelEnum) { boolean result = (boolean) redisTemplate.execute(new RedisCallback<Boolean>() { @Override public Boolean doInRedis(RedisConnection connection) throws DataAccessException { RedisSerializer<String> serializer = redisTemplate.getStringSerializer(); for (Map<String, Object> map : list) { byte[] key = serializer .serialize(formatKey(ctimsModelEnum, map.get("key").toString())); byte[] hkey = serializer.serialize(map.get("hkey").toString()); byte[] values = serializer.serialize(map.get("value").toString()); connection.hSet(key, hkey, values); } return true; } }, false, true); return result; } /*** * 模糊搜索key值是否存在,spring-redis 版本號在1.8之后的不需要關閉游標,之前的需要關閉游標。 * @param modelEnum * @param key * @param count * @return */ public boolean scan(CtimsModelEnum modelEnum, String key, long count) throws Exception { RedisConnection redisConnection = redisTemplate.getConnectionFactory().getConnection(); Cursor cursor = redisConnection .scan(ScanOptions.scanOptions().match(formatKey(modelEnum, key)).count(count).build()); try { Boolean isHas = cursor.hasNext(); return isHas; } catch (Exception e) { logger.error("redis 查詢key是否存在 異常:" + formatKey(modelEnum, key), e); return false; } finally { if (null != cursor) { cursor.close(); } } } }
import org.springframework.util.StringUtils; public enum CtimsModelEnum { CTIMS_COMM_CAP("comm", "公共"); private String code; private String desc; public static CtimsModelEnum getByCode(String code) { if (StringUtils.isEmpty(code)) { return null; } else { CtimsModelEnum[] var1 = values(); int var2 = var1.length; for(int var3 = 0; var3 < var2; ++var3) { CtimsModelEnum ctimsModelEnum = var1[var3]; if (ctimsModelEnum.getCode().equals(code)) { return ctimsModelEnum; } } return null; } } private CtimsModelEnum(String code, String desc) { this.code = code; this.desc = desc; } public String getCode() { return this.code; } public void setCode(String code) { this.code = code; } public String getDesc() { return this.desc; } public void setDesc(String desc) { this.desc = desc; } }