欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBoot集成Redis及Redis使用方法

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

應(yīng)用背景

將一些經(jīng)常展現(xiàn)和不會頻繁變更的數(shù)據(jù),存放在存取速率更快的地方。 緩存就是一個存儲器,在技術(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是一個使用ANSI C編寫的開源、包含多種數(shù)據(jù)結(jié)構(gòu)、支持網(wǎng)絡(luò)、基于內(nèi)存、可選持久性的鍵值對存儲數(shù)據(jù)庫。
  • Redis使用場景:緩存系統(tǒng)(“熱點”數(shù)據(jù):高頻讀、低頻寫)、計數(shù)器、消息隊列系統(tǒng)、排行榜、社交網(wǎng)絡(luò)和實時系統(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版本的默認的Redis客戶端是 Jedis實現(xiàn)的,需要導(dǎo)入jedis依賴,而springboot 2.x版本中默認客戶端是用 lettuce實現(xiàn)的,需要導(dǎo)入spring-boot-starter-data-redis依賴。這兩種方式使用的都是 TCP協(xié)議??梢岳斫鉃椋涸蹅兺ㄟ^程序是不能直接連接 Redis,得利用客戶端工具才能進行連接。比較常用的有兩種:Jedis、Lettuce。既然 Lettuce 和 Jedis 的都是連接 Redis Server 的客戶端,那么它們有什么區(qū)別呢?
  • Jedis使用直連方式連接Redis Server,在多線程環(huán)境下存在線程安全問題, 因此需要增加連接池來解決線程安全的問題,同時可以限制redis客戶端的數(shù)量, 但這種直連方式基于傳統(tǒng)I/O模式,是阻塞式傳輸。
  • 而 Lettuce 是 一種可伸縮,線程安全,完全非阻塞的Redis客戶端,底層基于netty通信,我們知道netty是基于NIO的非阻塞通信, 天生支持高并發(fā),因此在在多線程環(huán)境下不存在線程安全問題,一個連接實例就可以滿足多線程環(huán)境下的并發(fā)訪問, 當(dāng)然實例不夠的情況下也可以按需增加實例,保證伸縮性。
  • 下面我們通過源碼的方式解析springboot是如何通過lettuce方式連接redis server的,以及springboot操作redis的底層原理。      

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

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

這里說說為什么要添加 org.apache.commons 依賴,如果不加,它會報錯: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  # 密碼(默認為空)
    timeout: 6000ms  # 連接超時時長(毫秒)
    expire: 3600 #7天不過期
    lettuce:
      pool:
        max-active: 100  # 連接池最大連接數(shù)(使用負值表示沒有限制)
        max-wait: -1ms      # 連接池最大阻塞等待時間(使用負值表示沒有限制)
        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
## 連接超時時間(毫秒)
spring.redis.timeout=3
## Redis服務(wù)器連接密碼(默認為空)
spring.redis.password=135246
## 連接池中的最大連接數(shù) (使用復(fù)數(shù)則標(biāo)識沒有限制) 默認 8
spring.redis.pool.max.active=100
## 連接池最大阻塞等待時間(使用負值表示沒有限制)默認 -1
spring.redis.pool.max.wait=-1
## 連接池中的最大空閑連接 默認 8 
spring.redis.pool.max.idle=20
## 連接池中的最小空閑連接 默認 0 
spring.redis.pool.max.idle=0

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

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

2.1:RedisTemplate中的幾個角色:

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

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

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

2.2.1:Spring 中提供了以下幾個序列化器:

  • 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;
/**
 * 項目名稱:springboot-demo
 * 類名稱:RedisConfig
 * 類描述:Redis配置
 * 創(chuàng)建時間: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工具包分為三個類
1:RedisUtils.java     Redis方法類主要記錄對redis的一些操作,增刪改查等。
2:RedisKeys.java    Redis自定義Key類,自定義配置,對redis操作時好分辨哪個key的數(shù)據(jù)
3:UserRedis.java    封裝類,將RedisUtils和RedisKey進行封裝,用戶直接操作此類

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;
/**
 * 項目名稱:springboot-demo
 * 類名稱:RedisUtils
 * 類描述:Redis工具類
 * 創(chuàng)建時間: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;
    /**默認過期時長,單位: 秒*/
    public final static long DEFAULT_EXPIRE = 60 * 10;
    /**從配置文件獲取 默認過期時長*/
    @Value("${spring.redis.expire}")
    public long expire;
    /**不設(shè)置過期時長 */
    public final static long NOT_EXPIRE = -1;
    /**它可以幫助我們快速的進行各個類型和Json類型的相互轉(zhuǎn)換*/
    private static final ObjectMapper MAPPER = new ObjectMapper();
    /**給指定key設(shè)置固定時間的有效期*/
    public void  expireAt(String key,Date date){
        redisTemplate.expireAt(key,date);
    }
    /**根據(jù)指定的key,獲取過期時間*/
    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可以傳一個值 或多個
    * 該注解屏蔽某些編譯時的警告信息
    * */
    @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è)置默認時間,調(diào)用下一個方法將值轉(zhuǎn)為JSON字符串*/
    public void set(String key, Object value){
        set(key, value, DEFAULT_EXPIRE);
    }
    /**將Object值轉(zhuǎn)為JSON字符串放入緩存,并設(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)用下一個get方法*/
    public <T> T get(String key, Class<T> clazz) {
        return get(key, clazz, NOT_EXPIRE);
    }
    /**根據(jù)key鍵獲取值并轉(zhuǎn)為對象 并重新設(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對象
        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的時候調(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對象*/
    private <T> T fromJson(String json, Class<T> clazz){
        return JSONUtil.toBean(json, clazz);
        //return JSON.parseObject(json,clazz);
    }
    /**將JsonObject轉(zhuǎn)為實體類對象,轉(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)計指定set的長度,當(dāng)指定key的set不存在時,返回null*/
    public Long countForSet(String key){
        return redisTemplate.opsForSet().size(key);
    }
    /**只有當(dāng)key不存在時才設(shè)置key的值,并返回true;當(dāng)key存在時不修改key的值,并返回false。*/
    public Boolean isMember(String value){
       return setOperations.isMember(RedisKeys.AutoKey,value);
    }
    /**向集合添加值并設(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;
/**
 * 項目名稱:user-center-service
 * 類名稱:RedisKeys
 * 類描述:redis所有的key
 * 創(chuàng)建時間:2023/7/27
 *
 * @author lzx
 * @version v1.0
 */
public class RedisKeys {
    //最大蘑菇號的key
    public final static String MAX_MOGUNO_KEY = "moguding:user:max_mogu_no";
    //短信驗證碼的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;
    }
    //緩存活躍蘑菇號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)計(實時發(fā)送【考勤,上崗,周報】)
    public final static String SCHOOL_COUNT= "moguding.school.count";
    //自動報告key
    public final static String AutoKey = "autoReport_set";
    //30天最后一次考勤
    public final static String LastSign = "moguding.last.sign";
    //省平臺基礎(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;
/**
 * 項目名稱:user-center-service
 * 類名稱:UserRedis
 * 類描述:UserRedis
 * 創(chuàng)建時間: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è)置默認過期時長 7天, set方法將value進行序列化(轉(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測試key是否存在
    public boolean hasKey(String key){
        if(key == null){
            return false;
        }
        String redisKey = RedisKeys.getRedisTestKey(key);
        return redisUtils.hasKey(redisKey);
    };*/
    //將今日活躍用戶的蘑菇號批量存進redis指定Set集合中
    public void addUserMoguNosToSet(List<String> moguNos){
        redisUtils.addBatchToSet(RedisKeys.ACTIVE_MOGU_NO,moguNos);
    }
    //將今日活躍用戶的蘑菇號緩存Set集合清空
    public void deleteForCacheUserMoguNo(){
        redisUtils.delete(RedisKeys.ACTIVE_MOGU_NO);
    }
    //判斷Redis測試key是否存在
    public boolean hasKey(String key){
        if(key == null){
            return false;
        }
        String redisKey = RedisKeys.getProvinceConfigKey(key);
        return redisUtils.hasKey(redisKey);
    };
    //從redis中統(tǒng)計活躍用戶數(shù)量
    public int countActiveUser(){
        Long Lnum  = redisUtils.countForSet(RedisKeys.ACTIVE_MOGU_NO);
        if(Lnum==null){
            return 0;
        }else {
            return Lnum.intValue();
        }
    }
    //省級平臺獲取redisKey
    public String getProvinceKey(String key){
        if(key == null){
            return null;
        }
        String redisKey = RedisKeys.getProvinceConfigKey(key);
        return redisUtils.get(redisKey);
    }
    //省級平臺向redis插入數(shù)據(jù)
    public void setProvinceDataToRedis(String key,String list){
        String keys = RedisKeys.getProvinceConfigKey(key);
         //配置文件默認保留時長
         redisUtils.setRedis(keys,list,redisUtils.expire);
    }
}

五:流程實現(xiàn)

模擬SpringBoot項目結(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測試接口
 * @version: v1.0
 */
@RestController
@Api(tags = {"Redis測試接口"},produces = "RedisTest_controller")
@RequestMapping("/redis")
public class RedisTestController {
    @Autowired
    RedisTestService redisTestService;
    private Logger logger = LoggerFactory.getLogger(RedisTestController.class);
    @ApiOperation(value = "Redis測試,將對象插入緩存",notes = "")
    @RequestMapping("/v1/test")
    public BaseResponse redisInsertBeanController(@RequestBody Item item){
        return redisTestService.redisInsertBeanService(item);
    }
    @ApiOperation(value = "Redis測試,將List插入緩存",notes = "")
    @RequestMapping("/v2/test")
    public BaseResponse redisInsertListController(@RequestBody Item item){
        return redisTestService.redisInsertListService(item);
    }
    @ApiOperation(value = "Redis測試,將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測試接口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è)置過期時間,若值不存在則重新插入緩存。"+
     "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方法不帶泛型默認返回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)對象方法把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("計算機");
        item1.setValue(10);
        list.add(item1);
        Item item2 =new Item();
        item2.setName("會計");
        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)文章

  • 啟動springboot應(yīng)用因未配置數(shù)據(jù)庫報錯的解決方案

    啟動springboot應(yīng)用因未配置數(shù)據(jù)庫報錯的解決方案

    這篇文章主要介紹了啟動springboot應(yīng)用因未配置數(shù)據(jù)庫報錯的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • java中通過行為參數(shù)化傳遞代碼方案

    java中通過行為參數(shù)化傳遞代碼方案

    大家好,本篇文章主要講的是java中通過行為參數(shù)化傳遞代碼方案,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下
    2022-02-02
  • Spring?Boot集成Milvus快速入門demo示例詳解

    Spring?Boot集成Milvus快速入門demo示例詳解

    Milvus是一種高性能向量數(shù)據(jù)庫,支持從筆記本到大型分布式系統(tǒng)的多環(huán)境運行,它以開源和云服務(wù)形式提供,是LFAI & Data Foundation的項目,采用Apache 2.0許可,Milvus特別支持高并行化和解耦的系統(tǒng)架構(gòu),使其能夠隨數(shù)據(jù)增長而擴展,支持各種復(fù)雜搜索功能,滿足企業(yè)級AI應(yīng)用需求
    2024-09-09
  • Spring、SpringMvc和SpringBoot的區(qū)別及說明

    Spring、SpringMvc和SpringBoot的區(qū)別及說明

    Spring框架提供了全面的Java開發(fā)解決方案,核心包括IOC和AOP,SpringMvc作為其中的WEB層開發(fā)框架,通過復(fù)雜的XML配置管理前端視圖和后臺邏輯,SpringBoot則簡化了配置,專注于微服務(wù)接口開發(fā),支持嵌入式服務(wù)器,提高了開發(fā)效率
    2024-10-10
  • 深入理解Spring事務(wù)原理

    深入理解Spring事務(wù)原理

    這篇文章主要帶領(lǐng)大家深入理解Spring事務(wù)原理,Spring事務(wù)的傳播屬性
    2016-07-07
  • Spring Boot + Kotlin整合MyBatis的方法教程

    Spring Boot + Kotlin整合MyBatis的方法教程

    前幾天由于工作需要,便開始學(xué)習(xí)了kotlin,java基礎(chǔ)扎實學(xué)起來也還算比較快,對于kotlin這個編程語言自然是比java有趣一些,下面這篇文章主要給大家介紹了關(guān)于Spring Boot + Kotlin整合MyBatis的方法教程,需要的朋友可以參考下。
    2018-01-01
  • RocketMQ NameServer保障數(shù)據(jù)一致性實現(xiàn)方法講解

    RocketMQ NameServer保障數(shù)據(jù)一致性實現(xiàn)方法講解

    這篇文章主要介紹了RocketMQ NameServer保障數(shù)據(jù)一致性實現(xiàn)方法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-12-12
  • springboot3+r2dbc響應(yīng)式編程實踐

    springboot3+r2dbc響應(yīng)式編程實踐

    本文主要介紹了springboot3+r2dbc響應(yīng)式編程實踐,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • Java 多線程實例詳解(二)

    Java 多線程實例詳解(二)

    本文主要介紹Java 多線程的資料整理,這里整理了詳細資料及相關(guān)示例代碼,有興趣的小伙伴可以參考下
    2016-09-09
  • 輕松掌握Java代理模式

    輕松掌握Java代理模式

    這篇文章主要幫助大家輕松掌握Java代理模式,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-09-09

最新評論