spring boot 使用redis 及redis工具类
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; } }