spring boot 使用redis 及redis工具类

1-添加maven依赖

 
        
            org.springframework.data
            spring-data-redis
            1.8.7.RELEASE
        

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 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 get(CtimsModelEnum modelEnum, String key, Class 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 get(CtimsModelEnum modelEnum, String key, Class 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 hget(CtimsModelEnum modelEnum, String key, String item, Class clazz) {
        String value = (String) redisTemplate.opsForHash().get(formatKey(modelEnum, key), item);
        return value == null ? null : fromJson(value, clazz);

    }

    /**
     * 获取hashKey对应的所有键值
     *
     * @param key 键
     * @return 对应的多个键值
     */
    public Map 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 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 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 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 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 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 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 fromJson(String json, Class clazz) {
        return GSON.fromJson(json, clazz);
    }

    /**
     * Function:  redis关键字生成
* * @author luxiangxing
* @date 2018/6/27 下午8:12
* @param
* @return
* @version */ private String formatKey(CtimsModelEnum modelEnum, String key) { return "ctims:" + modelEnum.getCode() + ":" + key; } private List formatKey(CtimsModelEnum modelEnum, String... key) { List 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> list, final CtimsModelEnum ctimsModelEnum) { boolean result = (boolean) redisTemplate.execute(new RedisCallback() { @Override public Boolean doInRedis(RedisConnection connection) throws DataAccessException { RedisSerializer serializer = redisTemplate.getStringSerializer(); for (Map 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> list, final CtimsModelEnum ctimsModelEnum) { boolean result = (boolean) redisTemplate.execute(new RedisCallback() { @Override public Boolean doInRedis(RedisConnection connection) throws DataAccessException { RedisSerializer serializer = redisTemplate.getStringSerializer(); for (Map 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(); } } } }

 

你可能感兴趣的:(Java,springboot,redis,spring,boot)