国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當(dāng)前位置: 首頁(yè) > news >正文

做網(wǎng)站的公司中國(guó)聯(lián)通業(yè)績(jī)

做網(wǎng)站的公司,中國(guó)聯(lián)通業(yè)績(jī),服務(wù)器重啟后網(wǎng)站打不開,大型網(wǎng)絡(luò)手游游戲排行榜目錄 應(yīng)用背景 Redis簡(jiǎn)介 更新問題 一:環(huán)境配置 1.1: 在pom.xml文件中添加依賴 1.2:配置SpringBoot核心配置文件application.properties 二:在Config文件夾中創(chuàng)建RedisConfig配置文件類 2.1:RedisTemplate中的幾個(gè)角色&am…

目錄

應(yīng)用背景

Redis簡(jiǎn)介

更新問題

一:環(huán)境配置

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

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

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

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

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

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

四:封裝Redis Utils工具包

4.1:RedisUtils.java

4.2:RedisKeys.java

4.3:UserRedis.java

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

1.RedisTestController

?2.RedisTestService

3.RedisTestServiceImpl

4.AttributeData

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


應(yīng)用背景

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

Redis簡(jiǎn)介

  • Redis介紹:Redis是現(xiàn)在最受歡迎的NoSQL數(shù)據(jù)庫(kù)之一,Redis是一個(gè)使用ANSI C編寫的開源、包含多種數(shù)據(jù)結(jié)構(gòu)、支持網(wǎng)絡(luò)、基于內(nèi)存、可選持久性的鍵值對(duì)存儲(chǔ)數(shù)據(jù)庫(kù)。
  • Redis使用場(chǎng)景:緩存系統(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ù)庫(kù)中取數(shù)據(jù),成功后,放到緩存中。
  • 命中:應(yīng)用程序從cache中取數(shù)據(jù),取到后返回。
  • 更新:先把數(shù)據(jù)存到數(shù)據(jù)庫(kù)中,成功后,再讓緩存失效。

更新問題

  1. 我們知道,在 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ū)別呢?
  2. Jedis使用直連方式連接Redis Server,在多線程環(huán)境下存在線程安全問題, 因此需要增加連接池來解決線程安全的問題,同時(shí)可以限制redis客戶端的數(shù)量, 但這種直連方式基于傳統(tǒng)I/O模式,是阻塞式傳輸。
  3. 而 Lettuce 是 一種可伸縮,線程安全,完全非阻塞的Redis客戶端,底層基于netty通信,我們知道netty是基于NIO的非阻塞通信, 天生支持高并發(fā),因此在在多線程環(huán)境下不存在線程安全問題,一個(gè)連接實(shí)例就可以滿足多線程環(huán)境下的并發(fā)訪問, 當(dāng)然實(shí)例不夠的情況下也可以按需增加實(shí)例,保證伸縮性。
  4. 下面我們通過源碼的方式解析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: 0host: 127.0.0.1port: 3304password: 123456  # 密碼(默認(rèn)為空)timeout: 6000ms  # 連接超時(shí)時(shí)長(zhǎng)(毫秒)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ù)庫(kù)索引
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 {@Autowiredprivate RedisConnectionFactory factory;@Beanpublic 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ù)**/@Beanpublic HashOperations<String, String, Object> hashOperations(RedisTemplate<String, Object> redisTemplate) {return redisTemplate.opsForHash();}/***  HashOperations* 操作 String 類型數(shù)據(jù)**/@Beanpublic ValueOperations<String, String> valueOperations(RedisTemplate<String, String> redisTemplate) {return redisTemplate.opsForValue();}/***  HashOperations* 操作 List 類型數(shù)據(jù)**/@Beanpublic ListOperations<String, Object> listOperations(RedisTemplate<String, Object> redisTemplate) {return redisTemplate.opsForList();}/***  HashOperations* 操作 Set 類型數(shù)據(jù)**/@Beanpublic SetOperations<String, Object> setOperations(RedisTemplate<String, Object> redisTemplate) {return redisTemplate.opsForSet();}/***  HashOperations* 操作 SortedSet 類型數(shù)據(jù)**/@Beanpublic 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);@Autowiredprivate RedisTemplate<String, Object> redisTemplate;@Autowiredprivate ValueOperations<String, String> valueOperations;@Autowiredprivate HashOperations<String, String, Object> hashOperations;@Autowiredprivate ListOperations<String, Object> listOperations;@Autowiredprivate SetOperations<String, Object> setOperations;@Autowiredprivate ZSetOperations<String, Object> zSetOperations;/**默認(rèn)過期時(shí)長(zhǎng),單位: 秒*/public final static long DEFAULT_EXPIRE = 60 * 10;/**從配置文件獲取 默認(rèn)過期時(shí)長(zhǎng)*/@Value("${spring.redis.expire}")public long expire;/**不設(shè)置過期時(shí)長(zhǎng) */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í)長(zhǎng)*/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的長(zhǎng)度,當(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)的keypublic final static String MAX_MOGUNO_KEY = "moguding:user:max_mogu_no";//短信驗(yàn)證碼的keypublic 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;}//用戶Tokenpublic 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)告keypublic 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 {@Autowiredprivate 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í)長(zhǎng) 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)獲取redisKeypublic 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í)長(zhǎng)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 {@AutowiredRedisTestService 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 {@AutowiredUserRedis 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)為JsonArrayMap<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ù)作為keyMap<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集合1List<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é)果:

?

http://m.aloenet.com.cn/news/32561.html

相關(guān)文章:

  • 網(wǎng)頁(yè)制作素材按鈕圖標(biāo)seo編輯招聘
  • 做服裝要看國(guó)外哪些網(wǎng)站長(zhǎng)尾關(guān)鍵詞挖掘
  • 兩學(xué)一做材料上哪個(gè)網(wǎng)站找最佳的搜索引擎
  • 可以自己做網(wǎng)站優(yōu)化嗎體驗(yàn)式營(yíng)銷經(jīng)典案例
  • 門戶網(wǎng)站建設(shè)談判搜狗站長(zhǎng)平臺(tái)主動(dòng)提交
  • 網(wǎng)站開發(fā)的具體流程網(wǎng)站發(fā)布平臺(tái)
  • 西寧網(wǎng)站seo公司seo推廣效果
  • 國(guó)內(nèi)頂尖網(wǎng)站設(shè)計(jì)公司口碑營(yíng)銷的定義
  • 免費(fèi)做外貿(mào)的網(wǎng)站深圳谷歌推廣公司
  • 幫彩票網(wǎng)站做流量提升seo賺錢方式
  • 東莞網(wǎng)站建設(shè) 環(huán)保設(shè)備自創(chuàng)網(wǎng)站
  • 武漢建站中心百度廣告競(jìng)價(jià)排名
  • 淘客網(wǎng)站要怎么做黑帽seo技巧
  • 政府網(wǎng)站建設(shè)事例常見的推廣方式有哪些
  • 遼河油田建設(shè)有限公司網(wǎng)站找個(gè)網(wǎng)站
  • 9420高清免費(fèi)視頻在線觀看武漢抖音seo搜索
  • 做網(wǎng)站需要懂什么廣州網(wǎng)頁(yè)定制多少錢
  • 做怎么樣的網(wǎng)站好如何自己弄個(gè)免費(fèi)網(wǎng)站
  • 怎么做一元購(gòu)網(wǎng)站代運(yùn)營(yíng)公司哪家好一些
  • 做網(wǎng)站靠教育賺錢seo的基礎(chǔ)優(yōu)化
  • com是什么網(wǎng)站廣告推廣策劃
  • 我的世界做披風(fēng)網(wǎng)站友情鏈接檢測(cè)的特點(diǎn)
  • 松原網(wǎng)站制作如何讓百度收錄自己的網(wǎng)站
  • 婁底網(wǎng)站建設(shè)的話術(shù)北京seo運(yùn)營(yíng)推廣
  • 網(wǎng)站建設(shè)基礎(chǔ)大綱文案軟文推廣有哪些
  • 網(wǎng)站開發(fā)用的那些語言怎么在百度發(fā)布自己的文章
  • 花店網(wǎng)站建設(shè)環(huán)境分析百度搜索什么關(guān)鍵詞能搜到網(wǎng)站
  • 午夜做網(wǎng)站營(yíng)銷網(wǎng)站的宣傳、推廣與運(yùn)作
  • 淘寶站內(nèi)推廣方式有哪些班級(jí)優(yōu)化大師使用心得
  • 許昌做網(wǎng)站漢獅網(wǎng)絡(luò)青島seo關(guān)鍵詞優(yōu)化公司