最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot集成Redis及Redis使用方法

 更新時(shí)間:2023年08月11日 09:16:20   作者:李指導(dǎo)、  
Redis是現(xiàn)在最受歡迎的NoSQL數(shù)據(jù)庫之一,Redis是一個(gè)使用ANSI C編寫的開源、包含多種數(shù)據(jù)結(jié)構(gòu)、支持網(wǎng)絡(luò)、基于內(nèi)存、可選持久性的鍵值對(duì)存儲(chǔ)數(shù)據(jù)庫,這篇文章主要介紹了SpringBoot集成Redis及Redis使用方法,需要的朋友可以參考下

應(yīng)用背景

將一些經(jīng)常展現(xiàn)和不會(huì)頻繁變更的數(shù)據(jù),存放在存取速率更快的地方。 緩存就是一個(gè)存儲(chǔ)器,在技術(shù)選型中,常用 Redis 作為緩存數(shù)據(jù)庫,可以幫我們分散掉數(shù)據(jù)庫的壓力,有了它能更好的支持并發(fā)性能,主要是在獲取資源方便性能優(yōu)化的關(guān)鍵方面??梢赃@樣理解redis位于數(shù)據(jù)庫和springboot框架之間,起到數(shù)據(jù)緩存的作用。

Redis簡介

  • Redis介紹:Redis是現(xiàn)在最受歡迎的NoSQL數(shù)據(jù)庫之一,Redis是一個(gè)使用ANSI C編寫的開源、包含多種數(shù)據(jù)結(jié)構(gòu)、支持網(wǎng)絡(luò)、基于內(nèi)存、可選持久性的鍵值對(duì)存儲(chǔ)數(shù)據(jù)庫。
  • Redis使用場景:緩存系統(tǒng)(“熱點(diǎn)”數(shù)據(jù):高頻讀、低頻寫)、計(jì)數(shù)器、消息隊(duì)列系統(tǒng)、排行榜、社交網(wǎng)絡(luò)和實(shí)時(shí)系統(tǒng)
  • Redis數(shù)據(jù)類型:Redis提供的數(shù)據(jù)類型主要分為5種自有類型和一種自定義類型,這5種自有類型包括:String類型、哈希類型、列表類型、集合類型和順序集合類型。

更新緩存模式 Cache aside這是最常用最常用的pattern了。其具體邏輯如下:

  • 失效:應(yīng)用程序先從cache取數(shù)據(jù),沒有得到,則從數(shù)據(jù)庫中取數(shù)據(jù),成功后,放到緩存中。
  • 命中:應(yīng)用程序從cache中取數(shù)據(jù),取到后返回。
  • 更新:先把數(shù)據(jù)存到數(shù)據(jù)庫中,成功后,再讓緩存失效。

更新問題

  • 我們知道,在 springboot 1.5.x版本的默認(rèn)的Redis客戶端是 Jedis實(shí)現(xiàn)的,需要導(dǎo)入jedis依賴,而springboot 2.x版本中默認(rèn)客戶端是用 lettuce實(shí)現(xiàn)的,需要導(dǎo)入spring-boot-starter-data-redis依賴。這兩種方式使用的都是 TCP協(xié)議??梢岳斫鉃椋涸蹅兺ㄟ^程序是不能直接連接 Redis,得利用客戶端工具才能進(jìn)行連接。比較常用的有兩種:Jedis、Lettuce。既然 Lettuce 和 Jedis 的都是連接 Redis Server 的客戶端,那么它們有什么區(qū)別呢?
  • Jedis使用直連方式連接Redis Server,在多線程環(huán)境下存在線程安全問題, 因此需要增加連接池來解決線程安全的問題,同時(shí)可以限制redis客戶端的數(shù)量, 但這種直連方式基于傳統(tǒng)I/O模式,是阻塞式傳輸。
  • 而 Lettuce 是 一種可伸縮,線程安全,完全非阻塞的Redis客戶端,底層基于netty通信,我們知道netty是基于NIO的非阻塞通信, 天生支持高并發(fā),因此在在多線程環(huán)境下不存在線程安全問題,一個(gè)連接實(shí)例就可以滿足多線程環(huán)境下的并發(fā)訪問, 當(dāng)然實(shí)例不夠的情況下也可以按需增加實(shí)例,保證伸縮性。
  • 下面我們通過源碼的方式解析springboot是如何通過lettuce方式連接redis server的,以及springboot操作redis的底層原理。      

?一:環(huán)境配置

1.1: 在pom.xml文件中添加依賴

這里說說為什么要添加 org.apache.commons 依賴,如果不加,它會(huì)報(bào)錯(cuò):Caused by: java.lang.ClassNotFoundException: org.apache.commons.pool2.impl.GenericObjectPoolConfig

<dependencies>
<!-- SpringBoot集成Redis的起步依賴 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
    <version>1.4.7.RELEASE</version>
</dependency>
<!--lettuce 依賴commons-pool-->
<dependency>
	<groupId>org.apache.commons</groupId>
	<artifactId>commons-pool2</artifactId>
	<version>2.8.0</version>
</dependency>
</dependencies>

1.2:配置SpringBoot核心配置文件application.properties

yml文件格式

spring:        
  redis:
    open: true  # 是否開啟redis緩存  true開啟   false關(guān)閉
    database: 0
    host: 127.0.0.1
    port: 3304
    password: 123456  # 密碼(默認(rèn)為空)
    timeout: 6000ms  # 連接超時(shí)時(shí)長(毫秒)
    expire: 3600 #7天不過期
    lettuce:
      pool:
        max-active: 100  # 連接池最大連接數(shù)(使用負(fù)值表示沒有限制)
        max-wait: -1ms      # 連接池最大阻塞等待時(shí)間(使用負(fù)值表示沒有限制)
        max-idle: 20      # 連接池中的最大空閑連接
        min-idle: 5       # 連接池中的最小空閑連接

properties文件格式

#Redis
##Redis數(shù)據(jù)庫索引
spring.redis.database=0
##Redis服務(wù)器地址
spring.redis.host=127.0.0.1
## Redis服務(wù)器連接端口
spring.redis.port=3304
## 連接超時(shí)時(shí)間(毫秒)
spring.redis.timeout=3
## Redis服務(wù)器連接密碼(默認(rèn)為空)
spring.redis.password=135246
## 連接池中的最大連接數(shù) (使用復(fù)數(shù)則標(biāo)識(shí)沒有限制) 默認(rèn) 8
spring.redis.pool.max.active=100
## 連接池最大阻塞等待時(shí)間(使用負(fù)值表示沒有限制)默認(rèn) -1
spring.redis.pool.max.wait=-1
## 連接池中的最大空閑連接 默認(rèn) 8 
spring.redis.pool.max.idle=20
## 連接池中的最小空閑連接 默認(rèn) 0 
spring.redis.pool.max.idle=0

二:在Config文件夾中創(chuàng)建RedisConfig配置文件類

RedisTemplate 是 Spring 操作 Redis 的重點(diǎn)內(nèi)容。 RedisTemplate是一個(gè)強(qiáng)大的類,首先它會(huì)自動(dòng)從 RedisConnectionFactory 工廠中獲取連接,然后執(zhí)行對(duì)應(yīng)的 Redis命令,提供了redis各種操作、異常處理及序列化,支持發(fā)布訂閱,并對(duì)spring 3.1 cache進(jìn)行了實(shí)現(xiàn),在最后還會(huì)關(guān)閉 Redis 的連接。

2.1:RedisTemplate中的幾個(gè)角色:

  • RedisSerializer:由于與Redis服務(wù)器的通信一定是使用字節(jié)數(shù)組完成的,所以RedisSerializer是將Java對(duì)象編碼解碼的組件
  • RedisOperations:封裝了一些Redis操作
  • XXXOperations:封裝了指定類型或功能的數(shù)據(jù)的操作,如ZSetOperations

2.2:為什么要自定義序列化:

RedisTemplate操作時(shí),默認(rèn)會(huì)采用jdkSerializable序列化機(jī)制,使得插入的值在redis客戶端看來會(huì)有亂碼 類似于: "\xac\ced\x00\x05t\x00\x03key" ,所以解決這個(gè)問題就需要修改默認(rèn)的序列化規(guī)則。

2.2.1:Spring 中提供了以下幾個(gè)序列化器:

  • Jackson2JsonRedisSerializer
  • JdkSerializationRedisSerializer
  • OxmSerializer
  • StringRedisSerializer
  • GenericToStringRedisSerializer
  • GenericJackson2JsonRedisSerializer

本章使用的是StringRedisSerializer, String序列化方式。

RedisConfig 所在結(jié)構(gòu)地址:

package com.lizexin.springbootdemo.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.*;
import org.springframework.data.redis.serializer.StringRedisSerializer;
/**
 * 項(xiàng)目名稱:springboot-demo
 * 類名稱:RedisConfig
 * 類描述:Redis配置
 * 創(chuàng)建時(shí)間:2023/08/04
 * @author lzx
 * @version v1.0
 */
@Configuration
public class RedisConfig {
    @Autowired
    private RedisConnectionFactory factory;
    @Bean
    public RedisTemplate<String, Object> redisTemplate() {
        // 將template 泛型設(shè)置為 <String, Object>
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        // 使用 String 序列化方式,序列化 KEY。
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        // 使用 String 序列化方式,序列化 VALUE。
        redisTemplate.setValueSerializer(new StringRedisSerializer());
        // 使用 String 序列化方式,序列化 HashKEY。
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        // 使用 String 序列化方式,序列化 ValueKEY。
        redisTemplate.setHashValueSerializer(new StringRedisSerializer());
        // 配置連接工廠
        redisTemplate.setConnectionFactory(factory);
        return redisTemplate;
    }
    /**
     *  HashOperations
     *  操作 Hash 類型數(shù)據(jù)
     **/
    @Bean
    public HashOperations<String, String, Object> hashOperations(RedisTemplate<String, Object> redisTemplate) {
        return redisTemplate.opsForHash();
    }
    /**
     *  HashOperations
     * 操作 String 類型數(shù)據(jù)
     **/
    @Bean
    public ValueOperations<String, String> valueOperations(RedisTemplate<String, String> redisTemplate) {
        return redisTemplate.opsForValue();
    }
    /**
     *  HashOperations
     * 操作 List 類型數(shù)據(jù)
     **/
    @Bean
    public ListOperations<String, Object> listOperations(RedisTemplate<String, Object> redisTemplate) {
        return redisTemplate.opsForList();
    }
    /**
     *  HashOperations
     * 操作 Set 類型數(shù)據(jù)
     **/
    @Bean
    public SetOperations<String, Object> setOperations(RedisTemplate<String, Object> redisTemplate) {
        return redisTemplate.opsForSet();
    }
    /**
     *  HashOperations
     * 操作 SortedSet 類型數(shù)據(jù)
     **/
    @Bean
    public ZSetOperations<String, Object> zSetOperations(RedisTemplate<String, Object> redisTemplate) {
        return redisTemplate.opsForZSet();
    }
}

四:封裝Redis Utils工具包

Redis工具包分為三個(gè)類
1:RedisUtils.java     Redis方法類主要記錄對(duì)redis的一些操作,增刪改查等。
2:RedisKeys.java    Redis自定義Key類,自定義配置,對(duì)redis操作時(shí)好分辨哪個(gè)key的數(shù)據(jù)
3:UserRedis.java    封裝類,將RedisUtils和RedisKey進(jìn)行封裝,用戶直接操作此類

redis 工具包 所在結(jié)構(gòu)地址:

4.1:RedisUtils.java

package com.lizexin.springbootdemo.utils.redis;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
 * 項(xiàng)目名稱:springboot-demo
 * 類名稱:RedisUtils
 * 類描述:Redis工具類
 * 創(chuàng)建時(shí)間:2023/08/04
 * @author lzx
 * @version v1.0
 */
@Component
public class RedisUtils {
    /**日志*/
    private static final Logger logger = LoggerFactory.getLogger(RedisUtils.class);
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private ValueOperations<String, String> valueOperations;
    @Autowired
    private HashOperations<String, String, Object> hashOperations;
    @Autowired
    private ListOperations<String, Object> listOperations;
    @Autowired
    private SetOperations<String, Object> setOperations;
    @Autowired
    private ZSetOperations<String, Object> zSetOperations;
    /**默認(rèn)過期時(shí)長,單位: 秒*/
    public final static long DEFAULT_EXPIRE = 60 * 10;
    /**從配置文件獲取 默認(rèn)過期時(shí)長*/
    @Value("${spring.redis.expire}")
    public long expire;
    /**不設(shè)置過期時(shí)長 */
    public final static long NOT_EXPIRE = -1;
    /**它可以幫助我們快速的進(jìn)行各個(gè)類型和Json類型的相互轉(zhuǎn)換*/
    private static final ObjectMapper MAPPER = new ObjectMapper();
    /**給指定key設(shè)置固定時(shí)間的有效期*/
    public void  expireAt(String key,Date date){
        redisTemplate.expireAt(key,date);
    }
    /**根據(jù)指定的key,獲取過期時(shí)間*/
    public long getExpire(String key) { return redisTemplate.getExpire(key, TimeUnit.SECONDS);}
    /**判斷key是否存在*/
    public boolean hasKey(String key) {
        try {
            return redisTemplate.hasKey(key);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
    * 刪除緩存, @param key可以傳一個(gè)值 或多個(gè)
    * 該注解屏蔽某些編譯時(shí)的警告信息
    * */
    @SuppressWarnings("unchecked")
    public void delete(String... key) {
        if (key != null && key.length > 0) {
            if (key.length == 1) {
                redisTemplate.delete(key[0]);
            } else {
                redisTemplate.delete((Collection<String>) CollectionUtils.arrayToList(key));
            }
        }
    }
    /**將Object值放如緩存并設(shè)置默認(rèn)時(shí)間,調(diào)用下一個(gè)方法將值轉(zhuǎn)為JSON字符串*/
    public void set(String key, Object value){
        set(key, value, DEFAULT_EXPIRE);
    }
    /**將Object值轉(zhuǎn)為JSON字符串放入緩存,并設(shè)置過期時(shí)長*/
    public void set(String key, Object value, long expire){
        valueOperations.set(key, objectToJson(value));
        if(expire != NOT_EXPIRE){
            redisTemplate.expire(key, expire, TimeUnit.SECONDS);
        }
    }
    /**根據(jù)key和泛型獲取值, 調(diào)用下一個(gè)get方法*/
    public <T> T get(String key, Class<T> clazz) {
        return get(key, clazz, NOT_EXPIRE);
    }
    /**根據(jù)key鍵獲取值并轉(zhuǎn)為對(duì)象 并重新設(shè)置過期時(shí)間*/
    public <T> T get(String key, Class<T> clazz, long expire) {
        String value = valueOperations.get(key);
        if(expire != NOT_EXPIRE){
            redisTemplate.expire(key, expire, TimeUnit.SECONDS);
        }
        //將Json字符串轉(zhuǎn)換為bean對(duì)象
        return value == null ? null : fromJson(value, clazz);
    }
    /**根據(jù)key鍵獲取值返回為String*/
    public String get(String key, long expire) {
        String value = valueOperations.get(key);
        if(expire != NOT_EXPIRE){
            redisTemplate.expire(key, expire, TimeUnit.SECONDS);
        }
        return value;
    }
    /*根據(jù)key獲取值*/
    public String get(String key) {
        return get(key, NOT_EXPIRE);
    }
     /**Object轉(zhuǎn)換為JSON字符串,在存reid的時(shí)候調(diào)用此方法*/
    private String objectToJson(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 JSONUtil.toJsonStr(object);
    }
    /**JSON字符串, 轉(zhuǎn)成javaBean對(duì)象*/
    private <T> T fromJson(String json, Class<T> clazz){
        return JSONUtil.toBean(json, clazz);
        //return JSON.parseObject(json,clazz);
    }
    /**將JsonObject轉(zhuǎn)為實(shí)體類對(duì)象,轉(zhuǎn)換異常將被拋出*/
    public static <T> T fromJsonToBean(JSONObject json, Class<T> beanClass) {
        return null == json ? null : json.toBean(beanClass);
    }
    /**將元素添加到指定set集合中*/
    public void addToSet(String key,String member){
        redisTemplate.opsForSet().add(key,member);
    }
    /**批量添加到指定set集合中*/
    public void addBatchToSet(String key,List<String> memberList) {
        Object[] members = memberList.toArray();
        redisTemplate.opsForSet().add(key,members);
    }
    /**統(tǒng)計(jì)指定set的長度,當(dāng)指定key的set不存在時(shí),返回null*/
    public Long countForSet(String key){
        return redisTemplate.opsForSet().size(key);
    }
    /**只有當(dāng)key不存在時(shí)才設(shè)置key的值,并返回true;當(dāng)key存在時(shí)不修改key的值,并返回false。*/
    public Boolean isMember(String value){
       return setOperations.isMember(RedisKeys.AutoKey,value);
    }
    /**向集合添加值并設(shè)置過期時(shí)間*/
    public Long addSetDataExpire(String value,String name,long expire){
     Long addSet =  setOperations.add(name,value);
        if(expire != NOT_EXPIRE){
            redisTemplate.expire(name, expire, TimeUnit.SECONDS);
        }
        return addSet;
    }
    /**向右邊批量添加元素*/
    public boolean addrightPushAll(String key, List<Object> value) {
        boolean var4;
        try {
            this.redisTemplate.opsForList().rightPushAll(key, value);
            boolean var3 = true;
            return var3;
        } catch (Exception var8) {
            logger.error("", var8);
            var4 = false;
        } finally {
            this.close();
        }
        return var4;
    }
    /**    * 獲取泛型的Collection Type
     * @param collectionClass 泛型的Collection
     * @param elementClasses 元素類
     * @return JavaType Java類型
     * @since 1.0*/
    public static JavaType getCollectionType(Class<?> collectionClass, Class<?>... elementClasses) {
        return MAPPER.getTypeFactory().constructParametricType(collectionClass, elementClasses);
    }
    private void close() {
        RedisConnectionUtils.unbindConnection(this.redisTemplate.getConnectionFactory());
    }
}

4.2:RedisKeys.java

package com.zhangtao.moguding.province.utils.redis;
/**
 * 項(xiàng)目名稱:user-center-service
 * 類名稱:RedisKeys
 * 類描述:redis所有的key
 * 創(chuàng)建時(shí)間:2023/7/27
 *
 * @author lzx
 * @version v1.0
 */
public class RedisKeys {
    //最大蘑菇號(hào)的key
    public final static String MAX_MOGUNO_KEY = "moguding:user:max_mogu_no";
    //短信驗(yàn)證碼的key
    public static String getSmsCodeKey(String key,Integer type){
        return "moguding:user:smsCode:" + key+":"+type;
    }
    //權(quán)限列表
    public final static String PERMISSIONS_USERAUTH_KEY = "moguding:permissions:permissions_userauth_list:";
    //參數(shù)配置
    public static String getUserConfigKey(String... key){
        return "moguding:user:config:" + key;
    }
    //用戶Token
    public final static String AUTH_TOKEN_KEY = "moguding:user:authToken:";
    //authtoken的key  web端
    public static String getAuthToken(String type,String userid){
        if("web".equals(type)){
            return AUTH_TOKEN_KEY+type+":" + userid;
        }else {
            return  getAuthToken(userid);
        }
    }
    //authtoken的key  app端
    public static String getAuthToken(String userid){
        return AUTH_TOKEN_KEY+ userid;
    }
    //緩存活躍蘑菇號(hào)key的
    public final static String ACTIVE_MOGU_NO= "moguding:user:active:";
    //緩存今日學(xué)校簽到排行榜
    public final static String SCHOOL_SIGN_RANK= "moguding:school:sign:rank";
    //學(xué)校統(tǒng)計(jì)(實(shí)時(shí)發(fā)送【考勤,上崗,周報(bào)】)
    public final static String SCHOOL_COUNT= "moguding.school.count";
    //自動(dòng)報(bào)告key
    public final static String AutoKey = "autoReport_set";
    //30天最后一次考勤
    public final static String LastSign = "moguding.last.sign";
    //省平臺(tái)基礎(chǔ)數(shù)據(jù)
    public static String getProvinceConfigKey(String key){
        return "moguding:province:config:" + key;
    }
}

4.3:UserRedis.java

package com.zhangtao.moguding.province.utils.redis;
import com.zhangtao.moguding.province.entity.UserConfigEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
/**
 * 項(xiàng)目名稱:user-center-service
 * 類名稱:UserRedis
 * 類描述:UserRedis
 * 創(chuàng)建時(shí)間:2019/5/27
 * @author lzx
 * @version v1.0
 */
/*
 *將RedisUtils的set方法和RedisKeys的key 封裝到一起
 * */
@Component
public class UserRedis {
    @Autowired
    private RedisUtils redisUtils;
    public void set(String key,String value) {
        if(key == null){
            return ;
        }
        String redisKey = RedisKeys.getUserConfigKey(key);
        redisUtils.set(redisKey, value,redisUtils.expire);
    }
    public void delete(String key) {
        if(key == null){
            return ;
        }
        String redisKey = RedisKeys.getUserConfigKey(key);
        redisUtils.delete(redisKey);
    }
    public String get(String key){
        if(key == null){
            return null;
        }
        String redisKey = RedisKeys.getUserConfigKey(key);
        return redisUtils.get(redisKey);
    }
    public UserConfigEntity getObject(String key){
        if(key == null){
            return null;
        }
        String redisKey = RedisKeys.getUserConfigKey(key);
        return redisUtils.get(redisKey, UserConfigEntity.class);
    }
    //向Redis添加值,設(shè)置默認(rèn)過期時(shí)長 7天, set方法將value進(jìn)行序列化(轉(zhuǎn)為JSON字符串)
/*    public void set(String key,Object value) {
        if(key == null){
            return ;
        }
        String redisKey = RedisKeys.getRedisTestKey(key);
        redisUtils.set(redisKey, value,redisUtils.expire);
    }
    public <T> T get(String key, Class<T> clazz){
        if(key == null){
            return null;
        }
        String redisKey = RedisKeys.getRedisTestKey(key);
        return redisUtils.get(redisKey,clazz);
    }
    //判斷Redis測(cè)試key是否存在
    public boolean hasKey(String key){
        if(key == null){
            return false;
        }
        String redisKey = RedisKeys.getRedisTestKey(key);
        return redisUtils.hasKey(redisKey);
    };*/
    //將今日活躍用戶的蘑菇號(hào)批量存進(jìn)redis指定Set集合中
    public void addUserMoguNosToSet(List<String> moguNos){
        redisUtils.addBatchToSet(RedisKeys.ACTIVE_MOGU_NO,moguNos);
    }
    //將今日活躍用戶的蘑菇號(hào)緩存Set集合清空
    public void deleteForCacheUserMoguNo(){
        redisUtils.delete(RedisKeys.ACTIVE_MOGU_NO);
    }
    //判斷Redis測(cè)試key是否存在
    public boolean hasKey(String key){
        if(key == null){
            return false;
        }
        String redisKey = RedisKeys.getProvinceConfigKey(key);
        return redisUtils.hasKey(redisKey);
    };
    //從redis中統(tǒng)計(jì)活躍用戶數(shù)量
    public int countActiveUser(){
        Long Lnum  = redisUtils.countForSet(RedisKeys.ACTIVE_MOGU_NO);
        if(Lnum==null){
            return 0;
        }else {
            return Lnum.intValue();
        }
    }
    //省級(jí)平臺(tái)獲取redisKey
    public String getProvinceKey(String key){
        if(key == null){
            return null;
        }
        String redisKey = RedisKeys.getProvinceConfigKey(key);
        return redisUtils.get(redisKey);
    }
    //省級(jí)平臺(tái)向redis插入數(shù)據(jù)
    public void setProvinceDataToRedis(String key,String list){
        String keys = RedisKeys.getProvinceConfigKey(key);
         //配置文件默認(rèn)保留時(shí)長
         redisUtils.setRedis(keys,list,redisUtils.expire);
    }
}

五:流程實(shí)現(xiàn)

模擬SpringBoot項(xiàng)目結(jié)構(gòu)調(diào)用

1.RedisTestController

package com.lizexin.springbootdemo.Controller;
import com.lizexin.springbootdemo.entity.Item;
import com.lizexin.springbootdemo.service.RedisTestService;
import com.zhangtao.common.dto.response.BaseResponse;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
 * @program: springboot-demo
 * @author: lzx
 * @Time: 2023/8/9  16:35
 * @description: Redis測(cè)試接口
 * @version: v1.0
 */
@RestController
@Api(tags = {"Redis測(cè)試接口"},produces = "RedisTest_controller")
@RequestMapping("/redis")
public class RedisTestController {
    @Autowired
    RedisTestService redisTestService;
    private Logger logger = LoggerFactory.getLogger(RedisTestController.class);
    @ApiOperation(value = "Redis測(cè)試,將對(duì)象插入緩存",notes = "")
    @RequestMapping("/v1/test")
    public BaseResponse redisInsertBeanController(@RequestBody Item item){
        return redisTestService.redisInsertBeanService(item);
    }
    @ApiOperation(value = "Redis測(cè)試,將List插入緩存",notes = "")
    @RequestMapping("/v2/test")
    public BaseResponse redisInsertListController(@RequestBody Item item){
        return redisTestService.redisInsertListService(item);
    }
    @ApiOperation(value = "Redis測(cè)試,將Map<String,Set<String>>插入緩存,取出來轉(zhuǎn)Map<String,JsonArry>",notes = "")
    @RequestMapping("/v3/test")
    public BaseResponse redisInsertMapController(@RequestBody Item item){
        return redisTestService.redisInsertMapService(item);
    }
}

 2.RedisTestService

package com.lizexin.springbootdemo.service;
import com.lizexin.springbootdemo.entity.Item;
import com.zhangtao.common.dto.response.BaseResponse;
/**
 * @program: springboot-demo
 * @author: lzx
 * @Time: 2023/8/9  22:55
 * @description: Redis測(cè)試接口Service
 * @version: v1.0
 */
public interface RedisTestService {
    BaseResponse redisInsertBeanService( Item item);
    BaseResponse redisInsertListService( Item item);
    BaseResponse redisInsertMapService( Item item);
}

3.RedisTestServiceImpl

package com.lizexin.springbootdemo.service.impl;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONArray;
import com.lizexin.springbootdemo.entity.Item;
import com.lizexin.springbootdemo.service.RedisTestService;
import com.lizexin.springbootdemo.utils.*;
import com.lizexin.springbootdemo.utils.redis.UserRedis;
import com.zhangtao.common.dto.response.BaseResponse;
import com.zhangtao.common.dto.response.ObjectResponse;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.stream.Collectors;
/**
 * @program: springboot-demo
 * @author: lzx
 * @Time: 2023/08/9  22:58
 * @description: test
 * @version: v1.0
 */
@Service
public class RedisTestServiceImpl implements RedisTestService {
    @Autowired
    UserRedis userRedis;
    private static final Logger logger = LoggerFactory.getLogger(RedisTestServiceImpl.class);
    @Override
    @ApiOperation(
     "通過key得到值并重新設(shè)置過期時(shí)間,若值不存在則重新插入緩存。"+
     "set方法封裝了 JSONUtil.toJsonStr"+ "get帶泛型的方法封裝了JSONUtil.toBean "
    )
    public BaseResponse redisInsertBeanService(Item item) {
        String redisKey= "redisInsertBeanService";
        System.out.println(redisKey);
        //判斷key值是否存在,如果存在則優(yōu)先取緩存
        if (userRedis.hasKey(redisKey)){
            Item jsonString=  userRedis.get(redisKey,Item.class);
            logger.info("存在值");
            logger.info(jsonString.toString());
            return ObjectResponse.resObj(jsonString);
        }else{
            //不存在則緩存
           Item item1= AttributeData.list9();
           logger.info("不存在值 插入");
           userRedis.set(redisKey,item1);
            return ObjectResponse.ok();
        }
    }
    @Override
    @ApiOperation("get方法不帶泛型默認(rèn)返回Json字符串,需要自行反序列化")
    public BaseResponse redisInsertListService(Item item) {
        //通過key得到值,
        String redisKey = "redisInsertListService";
        System.out.println(redisKey);
        //判斷key值是否存在,如果存在則優(yōu)先取緩存
        if (userRedis.hasKey(redisKey)){
            List<Item> list = JSONArray.parseArray(userRedis.get(redisKey),Item.class);
            logger.info("存在值");
            logger.info(list.toString());
            return ObjectResponse.resObj(list);
        }else{
            //不存在則緩存
            List<Item> list= AttributeData.list8();
            logger.info("不存在值 插入");
            userRedis.set(redisKey,list);
            return ObjectResponse.ok();
        }
    }
    @Override
    @ApiOperation("")
    public BaseResponse redisInsertMapService(Item item) {
        //通過key得到值,
        String redisKey= "redisInsertMapService";
        System.out.println(redisKey);
        //判斷key值是否存在,如果存在則優(yōu)先取緩存
        if (userRedis.hasKey(redisKey)){
            String jsonString=  userRedis.get(redisKey);
            //可以通過JSonString轉(zhuǎn)對(duì)象方法把Vlue值從Set轉(zhuǎn)為JsonArray
            Map<String,JSONArray> arrayMap= JSONUtil.toBean(jsonString,Map.class);
            logger.info("存在值");
            logger.info(arrayMap.toString());
            return ObjectResponse.resObj(arrayMap);
        }else{
            //不存在則緩存
            List<Item> list= AttributeData.list10();
            //根據(jù)key轉(zhuǎn)map,之后將Value換成set集合
            //將集合添加至Map 指定參數(shù)作為key
            Map<String,List<Item>> map = new HashMap();
            Map<String,Set<String>>setMap =new HashMap<>();
            map = list.stream().collect(Collectors.groupingBy(Item::getName,Collectors.toList()));
            for (Map.Entry<String,List<Item>> key:map.entrySet()){
                Set<String> set = new HashSet<>();
                key.getValue().forEach(c->{
                   set.add(c.getValue());
                });
                setMap.put(key.getKey(), set);
            }
            logger.info("不存在值 插入");
            userRedis.set(redisKey,setMap);
            return ObjectResponse.ok();
        }
    }
}

4.AttributeData

package com.lizexin.springbootdemo.utils;
import com.lizexin.springbootdemo.dto.CommonInterfaceDto;
import com.lizexin.springbootdemo.dto.InformationDatasDto;
import com.lizexin.springbootdemo.dto.export.ExportGxySchoolFlowDto;
import com.lizexin.springbootdemo.entity.Item;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * @program: springboot-demo
 * @author: lzx
 * @Time: 2023/8/9  22:55
 * @description: 常用數(shù)據(jù)集
 * @version: v1.0
 */
public class AttributeData {
        public static  List<Map<String,Object>> list1 (){
            //構(gòu)建List集合1
            List<Map<String,Object>> list1 = new ArrayList<>();
            Map<String,Object> data=new HashMap<>();
            data.put("userId","100001");
            data.put("userName","唐僧");
            list1.add(data);
            data=new HashMap<>();
            data.put("userId","100002");
            data.put("userName","八戒");
            list1.add(data);
            data=new HashMap<>();
            data.put("userId","100003");
            data.put("userName","悟空");
            list1.add(data);
            data=new HashMap<>();
            data.put("userId","100004");
            data.put("userName","沙僧");
            list1.add(data);
            return list1;
        }
        public static  List<Map<String,Object>> list2(){
            Map<String,Object> data=new HashMap<>();
            List<Map<String,Object>> list2 = new ArrayList<>();
            data=new HashMap<>();
            data.put("userId","100001");
            data.put("gender","男");
            data.put("age",20);
            list2.add(data);
            data=new HashMap<>();
            data.put("userId","100002");
            data.put("gender","雄");
            data.put("age",1000);
            list2.add(data);
            data=new HashMap<>();
            data.put("userId","100003");
            data.put("gender","雄");
            data.put("age",600);
            list2.add(data);
            data=new HashMap<>();
            data.put("userId","100004");
            data.put("gender","男");
            data.put("age",800);
            list2.add(data);
            return list2;
        }
        public static List<InformationDatasDto> list3(){
            List<InformationDatasDto> list = new ArrayList<>();
            InformationDatasDto info = new InformationDatasDto();
            info.setStudentId("10000");
            info.setStudent_name("張三");
            list.add(info);
            info = new InformationDatasDto();
            info.setStudentId("10001");
            info.setStudent_name("里李四");
            list.add(info);
            info = new InformationDatasDto();
            info.setStudentId("10002");
            info.setStudent_name("王五");
            list.add(info);
            info = new InformationDatasDto();
            info.setStudentId("10003");
            info.setStudent_name("趙六");
            list.add(info);
            info = new InformationDatasDto();
            info.setStudentId("10004");
            info.setStudent_name("馬七");
            list.add(info);
            return list;
        }
    public static List<InformationDatasDto> list4(){
        List<InformationDatasDto> list = new ArrayList<>();
        InformationDatasDto info = new InformationDatasDto();
        info.setStudentId("北京");
        info.setStudent_name("張三");
        list.add(info);
        info = new InformationDatasDto();
        info.setStudentId("北京省");
        info.setStudent_name("里李四");
        list.add(info);
        info = new InformationDatasDto();
        info.setStudentId("湖北省");
        info.setStudent_name("王五");
        list.add(info);
        info = new InformationDatasDto();
        info.setStudentId("湖北");
        info.setStudent_name("趙六");
        list.add(info);
        info = new InformationDatasDto();
        info.setStudentId("海南");
        info.setStudent_name("馬七");
        list.add(info);
        return list;
    }
    public static List<ExportGxySchoolFlowDto> list5(){
        List<ExportGxySchoolFlowDto> list = new ArrayList<>();
        ExportGxySchoolFlowDto info = new ExportGxySchoolFlowDto();
        info.setSchoolName("齊齊哈爾大學(xué)");
        info.setDatas("黑龍江省");
        info.setValue(10);
        list.add(info);
        info = new ExportGxySchoolFlowDto();
        info.setSchoolName("齊齊哈爾大學(xué)");
        info.setDatas("黑龍江");
        info.setValue(20);
        list.add(info);
        info = new ExportGxySchoolFlowDto();
        info.setSchoolName("齊齊哈爾大學(xué)");
        info.setDatas("黑龍江省哈爾濱市");
        info.setValue(20);
        list.add(info);
        info = new ExportGxySchoolFlowDto();
        info.setSchoolName("齊齊哈爾大學(xué)");
        info.setDatas("甘肅省");
        info.setValue(20);
        list.add(info);
        info = new ExportGxySchoolFlowDto();
        info.setSchoolName("哈爾濱大學(xué)");
        info.setDatas("黑龍江");
        info.setValue(20);
        list.add(info);
        info = new ExportGxySchoolFlowDto();
        info.setSchoolName("武漢職業(yè)大學(xué)");
        info.setDatas("北京市");
        info.setValue(10);
        list.add(info);
        info = new ExportGxySchoolFlowDto();
        info.setSchoolName("黑河市大學(xué)");
        info.setDatas("北京");
        info.setValue(10);
        list.add(info);
        return list;
    }
    public static List<CommonInterfaceDto.ItemBatchDataDto> list6(){
        List<CommonInterfaceDto.ItemBatchDataDto> list =new ArrayList<>();
        CommonInterfaceDto.ItemBatchDataDto item1 =new CommonInterfaceDto.ItemBatchDataDto();
        item1.setSchoolName("雙高校");
        item1.setData(10);
        item1.setBatchName("19年");
        list.add(item1);
        CommonInterfaceDto.ItemBatchDataDto item2 =new CommonInterfaceDto.ItemBatchDataDto();
        item2.setSchoolName("雙高校");
        item2.setData(20);
        item2.setBatchName("20年");
        list.add(item2);
        CommonInterfaceDto.ItemBatchDataDto item3 =new CommonInterfaceDto.ItemBatchDataDto();
        item3.setSchoolName("雙高校");
        item3.setData(30);
        item3.setBatchName("21年");
        list.add(item3);
        CommonInterfaceDto.ItemBatchDataDto item4 =new CommonInterfaceDto.ItemBatchDataDto();
        item4.setSchoolName("雙高校");
        item4.setData(40);
        item4.setBatchName("22年");
        list.add(item4);
        return list;
    }
    public static List<CommonInterfaceDto.ItemBatchDataDto> list7(){
        List<CommonInterfaceDto.ItemBatchDataDto> list =new ArrayList<>();
        CommonInterfaceDto.ItemBatchDataDto item1 =new CommonInterfaceDto.ItemBatchDataDto();
        item1.setSchoolName("鄭州經(jīng)貿(mào)學(xué)院");
        item1.setData(60);
        item1.setBatchName("19年");
        list.add(item1);
        CommonInterfaceDto.ItemBatchDataDto item2 =new CommonInterfaceDto.ItemBatchDataDto();
        item2.setSchoolName("鄭州經(jīng)貿(mào)學(xué)院");
        item2.setData(10);
        item2.setBatchName("22年");
        list.add(item2);
        return list;
    }
    public static List<Item> list8(){
        List<Item> list =new ArrayList<>();
        Item item1 =new Item();
        item1.setName("計(jì)算機(jī)");
        item1.setValue(10);
        list.add(item1);
        Item item2 =new Item();
        item2.setName("會(huì)計(jì)");
        item2.setValue(20);
        list.add(item2);
        Item item3 =new Item();
        item3.setName("銷售");
        item3.setValue(30);
        list.add(item3);
        Item item4 =new Item();
        item4.setName("老師");
        item4.setValue(40);
        list.add(item4);
        Item item5 =new Item();
        item5.setName("醫(yī)學(xué)");
        item5.setValue(40);
        list.add(item5);
        Item item6 =new Item();
        item6.setName("農(nóng)業(yè)");
        item6.setValue(94);
        list.add(item6);
        Item item7 =new Item();
        item7.setName("工程");
        item7.setValue(100);
        list.add(item7);
        return list;
    }
    public static Item list9(){
        Item item7 =new Item();
        item7.setName("工程");
        item7.setValue(100);
        return item7;
    }
    public static List<Item> list10(){
        List<Item> list =new ArrayList<>();
        Item item1 =new Item();
        item1.setName("河南省");
        item1.setValue("鄭州市");
        list.add(item1);
        Item item2 =new Item();
        item2.setName("河南省");
        item2.setValue("洛陽市");
        list.add(item2);
        Item item3 =new Item();
        item3.setName("河南省");
        item3.setValue("開封市");
        list.add(item3);
        Item item4 =new Item();
        item4.setName("湖北省");
        item4.setValue("武漢市");
        list.add(item4);
        Item item5 =new Item();
        item5.setName("湖北省");
        item5.setValue("襄陽市");
        list.add(item5);
        Item item6 =new Item();
        item6.setName("湖北省");
        item6.setValue("潛江市");
        list.add(item6);
        Item item7 =new Item();
        item7.setName("湖北省");
        item7.setValue("荊州市");
        list.add(item7);
        Item item8 =new Item();
        item8.setName("北京");
        item8.setValue("北京市");
        list.add(item8);
        return list;
    }
}

 調(diào)用結(jié)果:

相關(guān)文章

  • 如何在IDEA中快速解決Jar沖突詳解

    如何在IDEA中快速解決Jar沖突詳解

    相信很多同學(xué)在過去做項(xiàng)目都遇到過Jar沖突的問題,在本地環(huán)境沒問題,一旦部署到測(cè)試或生產(chǎn)環(huán)境突然就啟動(dòng)報(bào)錯(cuò),報(bào)類似classNotFound的Exception,本文詳細(xì)整理了如何在IDEA中快速解決Jar沖突,需要的朋友可以參考下
    2021-06-06
  • java實(shí)現(xiàn)數(shù)字轉(zhuǎn)大寫的方法

    java實(shí)現(xiàn)數(shù)字轉(zhuǎn)大寫的方法

    這篇文章主要介紹了 java實(shí)現(xiàn)數(shù)字轉(zhuǎn)大寫的方法的相關(guān)資料,希望通過本文能幫助到大家,讓大家實(shí)現(xiàn)這樣的功能,需要的朋友可以參考下
    2017-10-10
  • Java以命令模式設(shè)計(jì)模式

    Java以命令模式設(shè)計(jì)模式

    這篇文章主要詳細(xì)的介紹Java以命令的模式設(shè)計(jì)模式,是用場景、優(yōu)缺點(diǎn)等都作有詳細(xì)介紹,需要的朋友請(qǐng)具體參考下面文章內(nèi)容
    2021-09-09
  • java如何發(fā)送get請(qǐng)求獲取數(shù)據(jù)(附代碼)

    java如何發(fā)送get請(qǐng)求獲取數(shù)據(jù)(附代碼)

    這篇文章主要給大家介紹了關(guān)于java如何發(fā)送get請(qǐng)求獲取數(shù)據(jù)的相關(guān)資料,Java中的GET請(qǐng)求方法是HTTP協(xié)議中的一種請(qǐng)求方式,用于向服務(wù)器請(qǐng)求獲取資源,需要的朋友可以參考下
    2023-10-10
  • 使用MappingJackson2XmlView實(shí)現(xiàn)JSON到XML的視圖轉(zhuǎn)換

    使用MappingJackson2XmlView實(shí)現(xiàn)JSON到XML的視圖轉(zhuǎn)換

    MappingJackson2XmlView來實(shí)現(xiàn)從JSON到XML格式的響應(yīng)轉(zhuǎn)換,本文將通過案例,將展示如何將JSON格式的數(shù)據(jù)轉(zhuǎn)換為XML格式,以滿足不同客戶端的數(shù)據(jù)交換需求,需要的朋友可以參考下
    2024-07-07
  • IDEA代碼規(guī)范&質(zhì)量檢查的實(shí)現(xiàn)

    IDEA代碼規(guī)范&質(zhì)量檢查的實(shí)現(xiàn)

    這篇文章主要介紹了IDEA代碼規(guī)范&質(zhì)量檢查的實(shí)現(xiàn),文中通過圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • Java調(diào)用bat執(zhí)行python腳本方式

    Java調(diào)用bat執(zhí)行python腳本方式

    文章介紹了如何在Windows環(huán)境下通過Java調(diào)用bat文件來執(zhí)行Python腳本,并解決了執(zhí)行過程中出現(xiàn)的中文亂碼問題,具體方法是修改bat文件的編碼格式為ANSI,這樣可以確保中文路徑不會(huì)因編碼問題而導(dǎo)致路徑錯(cuò)誤
    2025-10-10
  • java中Lamda表達(dá)式講解

    java中Lamda表達(dá)式講解

    本文詳細(xì)講解了java中的Lamda表達(dá)式,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-12-12
  • spring?boot?3使用?elasticsearch?提供搜索建議的實(shí)例詳解

    spring?boot?3使用?elasticsearch?提供搜索建議的實(shí)例詳解

    這篇文章主要介紹了spring?boot3使用elasticsearch提供搜索建議,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-08-08
  • 解決JSONObject.toJSONString()輸出null的問題

    解決JSONObject.toJSONString()輸出null的問題

    這篇文章主要介紹了解決JSONObject.toJSONString()輸出null的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-02-02

最新評(píng)論

讷河市| 东安县| 文化| 宿州市| 鄄城县| 湖北省| 东平县| 宿州市| 定安县| 九江县| 晋中市| 科技| 宝兴县| 买车| 如皋市| 长岛县| 建始县| 鄂伦春自治旗| 高淳县| 包头市| 航空| 唐山市| 花莲市| 泾源县| 巴里| 象山县| 明光市| 桂林市| 蕲春县| 合川市| 茶陵县| 监利县| 新巴尔虎右旗| 四子王旗| 华阴市| 思茅市| 改则县| 旺苍县| 濮阳县| 宿迁市| 三台县|