Spring Boot 整合Redis


Spring Boot 整合Redis

導入依賴

<!-- springboot整合redis -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--guawa工具類-->
<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>27.0.1-jre</version>
</dependency>

配置文件

spring:
  redis:
    database: 0
    # Redis服務器地址 寫你的ip
    host: 0.0.0.0
    # Redis服務器連接端口
    port: 6379
    # Redis服務器連接密碼(默認為空)
    password: 
    # 連接池最大連接數(使用負值表示沒有限制  類似於mysql的連接池
    jedis:
      pool:
        max-active: 200
        # 連接池最大阻塞等待時間(使用負值表示沒有限制) 表示連接池的鏈接拿完了 現在去申請需要等待的時間
        max-wait: -1
        # 連接池中的最大空閑連接
        max-idle: 10
        # 連接池中的最小空閑連接
        min-idle: 0
  # 連接超時時間(毫秒) 去鏈接redis服務端
    timeout: 6000

配置RedisTemplate

@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
        RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>();
        //設置工廠鏈接
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        //設置自定義序列化方式
        setSerializeConfig(redisTemplate, redisConnectionFactory);
        return redisTemplate;
    }

    private void setSerializeConfig(RedisTemplate<String, Object> redisTemplate, RedisConnectionFactory redisConnectionFactory) {
        //對字符串采取普通的序列化方式 適用於key 因為我們一般采取簡單字符串作為key
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        //普通的string類型的key采用 普通序列化方式
        redisTemplate.setKeySerializer(stringRedisSerializer);
        //普通hash類型的key也使用 普通序列化方式
        redisTemplate.setHashKeySerializer(stringRedisSerializer);
        //解決查詢緩存轉換異常的問題  大家不能理解就直接用就可以了 這是springboot自帶的jackson序列化類,但是會有一定問題
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        //普通的值采用jackson方式自動序列化
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        //hash類型的值也采用jackson方式序列化
        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
        //屬性設置完成afterPropertiesSet就會被調用,可以對設置不成功的做一些默認處理
        redisTemplate.afterPropertiesSet();
    }
}

Redis工具類

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Component
@Slf4j
public class RedisUtils {

    @Autowired
    private RedisTemplate<String,Object> redisTemplate;

    /**
     * @param key
     * @return 獲得值
     * redis有五種數據類型 opsForValue表示是操作字符串類型
     */
    public Object get(String key){
        return  key == null ? null : redisTemplate.opsForValue().get(key);
    }
    //本來只可以放入string類型,但是我們配置了自動序列化所以這兒可以傳入object
    public boolean set(String key,Object value){
        try{
            redisTemplate.opsForValue().set(key,value);
            return true;
        }catch (Exception e){
            log.error("redis set value exception:{}",e);
            return false;
        }
    }

    /**
     * 原子操作
     * @param key
     * @param value
     * @param expire 過期時間 秒
     * @return
     */
    public boolean setex(String key,Object value,long expire){
        try{//TimeUnit.SECONDS指定類型為秒
            redisTemplate.opsForValue().set(key,value,expire, TimeUnit.SECONDS);
            return true;
        }catch (Exception e){
            log.error("redis set value and expire exception:{}",e);
            return false;
        }
    }

    /**
     * 非原子操作
     * @param key
     * @param expire
     * @return
     */
    public boolean expire(String key,long expire){
        try{//這兒沒有ops什么的是因為每種數據類型都能設置過期時間
            redisTemplate.expire(key,expire,TimeUnit.SECONDS);
            return true;
        }catch (Exception e){
            log.error("redis set key expire exception:{}",e);
            return false;
        }
    }

    /**
     *
     * @param key
     * @return 獲取key的過期時間
     */
    public long ttl(String key){
        return redisTemplate.getExpire(key);
    }

    /**
     *
     * @param keys 刪除key 可變參數
     */
    public void del(String ...keys){
        if(keys!=null&&keys.length>0) {
            redisTemplate.delete((Collection<String>) CollectionUtils.arrayToList(keys));
        }
    }

    /**
     *
     * @param key
     * @param step  傳入正數 就是加多少 傳入負數就是減多少
     * @return
     */
    public long incrBy(String key,long step){
        return redisTemplate.opsForValue().increment(key,step);
    }

    /**
     *
     * @param key
     * @param value
     * @return  如果該key存在就返回false 設置不成功 key不存在就返回ture設置成功
     */
    public boolean setnx(String key,Object value){
        return redisTemplate.opsForValue().setIfAbsent(key,value);
    }

    /**
     *  原子操作
     * @param key
     * @param value
     * @param expire  在上面方法加上過期時間設置
     * @return
     */
    public boolean setnxAndExpire(String key,Object value,long expire){
        return redisTemplate.opsForValue().setIfAbsent(key,value,expire,TimeUnit.SECONDS);
    }

    /**
     *
     * @param key
     * @param value
     * @return  如果該key存在就返回之前的value  不存在就返回null
     */
    public Object getAndSet(String key,Object value){
        return redisTemplate.opsForValue().getAndSet(key,value);
    }

    /**
     *
     * @param key
     * @return 判斷key是否存在
     */
    public boolean hasKey(String key){
        return redisTemplate.hasKey(key);
    }

    /***list的長度**/
    public long llen(String key){
        return redisTemplate.opsForList().size(key);
    }

    /**
     * 獲取key中index位置的值,負數就反過來數,-1為最后一個
     * @param key
     * @param index
     * @return
     */
    public Object lgetByIndex(String key,long index){
        try {
            return redisTemplate.opsForList().index(key, index);
        } catch (Exception e) {
            log.error("redis lgetByIndex error,key:{},index:{}exception:{}",key,index,e);
            return null;
        }
    }
    /**
     * 將list放入緩存
     * @param key 鍵
     * @param value 值
     * @return
     */
    public boolean lrpush(String key, Object value) {
        try {
            redisTemplate.opsForList().rightPush(key, value);
            return true;
        } catch (Exception e) {
            log.error("redis lrpush error,key:{},value:{}exception:{}",key,value,e);
            return false;
        }
    }
    /**
     * 將list放入緩存
     * @param key 鍵
     * @param value 值
     * @param time 時間(秒)
     * @return
     */
    public boolean lrpush(String key, Object value, long time) {
        try {
            redisTemplate.opsForList().rightPush(key, value);
            if (time > 0)
                expire(key, time);
            return true;
        } catch (Exception e) {
            log.error("redis lrpush error,key:{},value:{},timeL{},exception:{}",key,value,time,e);
            return false;
        }
    }
    /**
     * 將list放入緩存
     * @param key 鍵
     * @param value 值
     * @return
     */
    public boolean lrpush(String key, List<Object> value) {
        try {
            redisTemplate.opsForList().rightPushAll(key, value);
            return true;
        } catch (Exception e) {
            log.error("redis lrpush error,key:{},value:{},exception:{}",key,value,e);
            return false;
        }
    }
    /**
     * 將list放入緩存
     *
     * @param key 鍵
     * @param value 值
     * @param time 時間(秒)
     * @return
     */
    public boolean lrpush(String key, List<Object> value, long time) {
        try {
            redisTemplate.opsForList().rightPushAll(key, value);
            if (time > 0)
                expire(key, time);
            return true;
        } catch (Exception e) {
            log.error("redis lrpush error,key:{},value:{},time:{},exception:{}",key,value,time,e);
            return false;
        }
    }
    /**
     * 根據索引修改list中的某條數據
     * @param key 鍵
     * @param index 索引
     * @param value 值
     * @return
     */
    public boolean lUpdateByIndex(String key, long index, Object value) {
        try {
            redisTemplate.opsForList().set(key, index, value);
            return true;
        } catch (Exception e) {
            log.error("redis lUpdateByIndex error,key:{},index:{},value:{},exception:{}",key,index,value,e);
            return false;
        }
    }
    /**
     * 移除N個值為value
     * @param key 鍵
     * @param count 移除多少個
     * @param value 值
     * @return 移除的個數
     */
    public long lrem(String key, long count, Object value) {
        try {
            Long remove = redisTemplate.opsForList().remove(key, count, value);
            return remove;
        } catch (Exception e) {
            log.error("redis lrem error,key:{},count:{},value:{},exception:{}",key,count,value,e);
            return 0;
        }
    }
    /*****hash數據類型方法   opsForHash表示是操作字符串類型*****/

    /**
     * @param key 健
     * @param field 屬性
     * @param value 值
     * @return
     */
    public boolean hset(String key, String field, Object value) {
        try {
            redisTemplate.opsForHash().put(key, field, value);
            return true;
        }catch (Exception e){
            log.error("redis hset eror,key:{},field:{},value:{}",key,field,value);
            return false;
        }
    }

    /**
     *
     * @param key
     * @param field
     * @param value
     * @param seconds(秒) 過期時間
     * @return
     */
    public boolean hset(String key, String field, Object value,long seconds) {
        try {
            redisTemplate.opsForHash().put(key, field, value);
            expire(key,seconds);//調用通用方法設置過期時間
            return true;
        }catch (Exception e){
            log.error("redis hset and expire eror,key:{},field:{},value:{},exception:{}",key,field,value,e);
            return false;
        }
    }

    /**
     * 獲取key中field屬性的值
     * @param key
     * @param field
     * @return
     */
    public Object hget(String key,String field){
        return redisTemplate.opsForHash().get(key,field);
    }

    /**
     * 獲取key中多個屬性的鍵值對,這兒使用map來接收
     * @param key
     * @param fields
     * @return
     */
    public Map<String,Object> hmget(String key, String...fields){
        Map<String,Object> map =  new HashMap<>();
        for (String field :fields){
            map.put(field,hget(key,field));
        }
        return map;
    }

    /**
     * @param key 獲得該key下的所有鍵值對
     * @return
     */
    public Map<Object, Object> hmget(String key){
        return redisTemplate.opsForHash().entries(key);
    }

    /**
     * @param key 獲得該key下的所有鍵值對
     * @return
     */
   @Autowired
   private JacksonUtil jacksonUtil;
    //map----json字符串---->對象
    public <T>T hmgetObject(String key,Class<T> tClass){
        Map<Object, Object> hmget = hmget(key);
        if(CollectionUtils.isEmpty(hmget)) return null;
        //查詢到了 先把數據轉成json字符串
        String s = jacksonUtil.writeAsString(hmget);
        //再把json字符串轉回對象
        return  jacksonUtil.readValue(s,tClass);
    }

    /**
     * @param key 鍵
     * @param map 對應多個鍵值
     * @return
     */
    public boolean hmset(String key,Map<Object,Object> map){
        try {
            redisTemplate.opsForHash().putAll(key, map);
            return true;
        }catch (Exception e){
            log.error("redis hmset eror,key:{},value:{},exception:{}",key,map,e);
            return false;
        }
    }
    public boolean hmset(String key,Object object){
        try {
            String s = jacksonUtil.writeAsString(object);
            Map<String, String> map = jacksonUtil.readValueMap(s);
            redisTemplate.opsForHash().putAll(key, map);
            return true;
        }catch (Exception e){
            log.error("redis hmset eror,key:{},object:{},exception:{}",key,object,e);
            return false;
        }
    }
    /**
     * @param key 鍵
     * @param map 對應多個鍵值
     *  @param seconds 過期時間(秒)
     * @return
     */
    public boolean hmset(String key,Map<String,Object> map,long seconds){
        try {
            redisTemplate.opsForHash().putAll(key, map);
            expire(key,seconds);
            return true;
        }catch (Exception e){
            log.error("redis hmset eror,key:{},value:{},expireTime,exception:{}",key,map,seconds,e);
            return false;
        }
    }

    /**
     *刪除key中的屬性
     * @param key
     * @param fields
     */
    public void hdel(String key,Object...fields){
        redisTemplate.opsForHash().delete(key,fields);
    }

    /**
     * 判斷key中是否存在某屬性
     * @param key
     * @param field
     * @return
     */
    public boolean hHashKey(String key,String field){
        return redisTemplate.opsForHash().hasKey(key,field);
    }

    /**
     * 對key中filed的value增加多少 如果是減少就傳入負數
     * @param key
     * @param field
     * @param step 正數增加,負數減少
     * @return
     */
    public double hincr(String key,String field,double step){
        return redisTemplate.opsForHash().increment(key,field,step);
    }

    /**
     * key中多少個
     * @param key
     * @return
     */
    public long hlen(String key){
        return redisTemplate.opsForHash().size(key);
    }
    /******其他方法用到在增加********/

    /***set集合***/
    /**
     * 獲取key中所有元素
     * @param key
     * @return
     */
    public Set<Object> sgetAll(String key){
        try {
            return redisTemplate.opsForSet().members(key);
        }catch (Exception e){
            log.error("redis sgetAll error,key:{},exception:{}",key,e);
            return null;
        }
    }

    /**
     * 判斷value是否在key中
     * @param key
     * @param value
     * @return
     */
    public boolean sexists(String key,Object value){
        try {
            return redisTemplate.opsForSet().isMember(key,value);
        }catch (Exception e){
            log.error("redis sexists error,key:{},value:{},exception:{}",key,value,e);
            return false;
        }
    }

    /**
     * 插入多個元素
     * @param key
     * @param values
     * @return  成功的個數
     */
    public long sset(String key ,Object...values){
        try {
            return redisTemplate.opsForSet().add(key,values);
        }catch (Exception e){
            log.error("redis sset error,key:{},value:{},values:{},exception:{}",key,values,e);
            return 0;
        }
    }

    /**
     * 添加元素並設置過期時間  (非原子操作)
     * @param key
     * @param time
     * @param values
     * @return
     */
    public long sset(String key ,long time,Object...values){
        try {
            long count = redisTemplate.opsForSet().add(key,values);
            expire(key,time);
            return count;
        }catch (Exception e){
            log.error("redis sset error,key:{},value:{},values:{},exception:{}",key,values,e);
            return 0;
        }
    }

    /**
     * 獲取set的長度
     * @param key
     * @return
     */
    public long sgetSize(String key){
        try {
            return redisTemplate.opsForSet().size(key);
        }catch (Exception e){
            log.error("redis sgetSize error,key:{},exception:{}",key,e);
            return 0;
        }
    }
    /**
     * 移除值為value的
     * @param key 鍵
     * @param values 值 可以是多個
     * @return 移除的個數
     */
    public long sRemove(String key, Object... values) {
        try {
            Long count = redisTemplate.opsForSet().remove(key, values);
            return count;
        } catch (Exception e) {
            log.error("redis sRemove error,key:{},values:{},exception:{}",key,values,e);
            return 0;
        }
    }

    /**
     * 隨機取count個元素  count為正數就取不重復的  負數就有可能重復
     * @param key
     * @param count
     * @return
     */
    public List<Object> sRandom(String key,long count) {
        try {
            return  redisTemplate.opsForSet().randomMembers(key,count);
        } catch (Exception e) {
            log.error("redis sRandom error,key:{},count:{},exception:{}",key,count,e);
            return null;
        }
    }
    /****zset工具類***/
    /**
     * 添加元素
     * @param key
     * @param member
     * @param score
     * @return
     */
    public  boolean zadd(String key,Object member,double score){
        try {
            return  redisTemplate.opsForZSet().add(key,member,score);
        } catch (Exception e) {
            log.error("redis zadd error,key:{},value:{},score:{},exception:{}",key,member,score,e);
            return false;
        }
    }
    public  Set<String> zrange(String key,int start,int end){

        try {
            Set<Object> range = redisTemplate.opsForZSet().
                    range(key, start, end);
            if(range==null||range.size()==0) return null;
            return   range.stream().
                    map(o->(String)o).collect(Collectors.toSet());
        } catch (Exception e) {
            log.error("redis zrange error,key:{},start:{},end:{},exception:{}",
                    key,start,end,e);
            return null;
        }
    }
/***這個有點多,就不一一寫了 大家用到什么去補全剩下的API
 * Set< V > range(K key, long start, long end); 下標范圍取
 * Long remove(K key, Object… values); 刪除元素
 *Double incrementScore(K key, V value, double delta); 增加分數
 * Long rank(K key, Object o); 當前元素的位置
 *Long reverseRank(K key, Object o); 反過來的位置
 *Set< TypedTuple< V >> rangeWithScores(K key, long start, long end); 下標取出來帶分數
 * Set< V > rangeByScore(K key, double min, double max); 根據分數取
 * Set< TypedTuple< V >> rangeByScoreWithScores(K key, double min, double max); 根據分數取 並攜帶分數
 * Set< TypedTuple< V >> rangeByScoreWithScores(K key, double min, double max, long offset, long count); 翻頁
 *Long count(K key, double min, double max); 統計分數段的個數
 *Long size(K key); 個數  底層就是card
 * Long zCard(K key); 個數
 * Double score(K key, Object o); 查看某個元素的分數
 * Long removeRange(K key, long start, long end); 根據下標刪除某個范圍
 * Long removeRangeByScore(K key, double min, double max); 刪除某個分數段
 * 等等
 * **/
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM