真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

SpringBoot用Redis實現(xiàn)數(shù)據(jù)緩存

這篇文章主要講解了“SpringBoot用redis實現(xiàn)數(shù)據(jù)緩存”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“SpringBoot用Redis實現(xiàn)數(shù)據(jù)緩存”吧!

創(chuàng)新互聯(lián)公司長期為上千多家客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊從業(yè)經(jīng)驗10年,關(guān)注不同地域、不同群體,并針對不同對象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺,與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為德城企業(yè)提供專業(yè)的做網(wǎng)站、網(wǎng)站建設(shè)德城網(wǎng)站改版等技術(shù)服務(wù)。擁有十余年豐富建站經(jīng)驗和眾多成功案例,為您定制開發(fā)。

一、緩存概念知識

1、是什么緩存

我們?nèi)粘I钪?,?jīng)常會接觸聽到緩存這個詞,例如,瀏覽器清空緩存,處理器緩存大小,磁盤緩存等等。經(jīng)過分類,可以將緩存分為:

  • 硬件緩存:一般指的是機(jī)器上的 CPU、硬盤等等組件的緩存區(qū)間,一般是利用的內(nèi)存作為一塊中轉(zhuǎn)區(qū)域,都通過內(nèi)存交互信息,減少系統(tǒng)負(fù)載,提供傳輸效率。

  • 客戶端緩存:一般指的是某些應(yīng)用,例如瀏覽器、手機(jī)App、視頻緩沖等等,都是在加載一次數(shù)據(jù)后將數(shù)據(jù)臨時存儲到本地,當(dāng)再次訪問時候先檢查本地緩存中是否存在,存在就不必去遠(yuǎn)程重新拉取,而是直接讀取緩存數(shù)據(jù),這樣來減少遠(yuǎn)端服務(wù)器壓力和加快載入速度。

  • 服務(wù)端緩存:一般指遠(yuǎn)端服務(wù)器上,考慮到客戶端請求量多,某些數(shù)據(jù)請求量大,這些熱點數(shù)據(jù)經(jīng)常要到數(shù)據(jù)庫中讀取數(shù)據(jù),給數(shù)據(jù)庫造成壓力,還有就是 IO、網(wǎng)絡(luò)等原因有一定延遲,響應(yīng)客戶端較慢。所以,在一些不考慮實時性的數(shù)據(jù)中,經(jīng)常將這些數(shù)據(jù)存在內(nèi)存中(內(nèi)存速度非??欤?,當(dāng)請求時候,能夠直接讀取內(nèi)存中的數(shù)據(jù)及時響應(yīng),借鑒Redis實戰(zhàn)學(xué)習(xí)筆記。

2、為什么使用緩存

用緩存,主要有解決 高性能 與 高并發(fā) 與 減少數(shù)據(jù)庫壓力。緩存本質(zhì)就是將數(shù)據(jù)存儲在內(nèi)存中,當(dāng)數(shù)據(jù)沒有發(fā)生本質(zhì)變化的時候,我們應(yīng)盡量避免直接連接數(shù)據(jù)庫進(jìn)行查詢,因為并發(fā)高時很可能會將數(shù)據(jù)庫壓塌,而是應(yīng)去緩存中讀取數(shù)據(jù),只有緩存中未查找到時再去數(shù)據(jù)庫中查詢,這樣就大大降低了數(shù)據(jù)庫的讀寫次數(shù),增加系統(tǒng)的性能和能提供的并發(fā)量。

SpringBoot用Redis實現(xiàn)數(shù)據(jù)緩存

3、緩存的優(yōu)缺點

優(yōu)點:

  • 加快了響應(yīng)速度

  • 減少了對數(shù)據(jù)庫的讀操作,數(shù)據(jù)庫的壓力降低。

缺點:

  • 內(nèi)存容量相對硬盤小。

  • 緩存中的數(shù)據(jù)可能與數(shù)據(jù)庫中數(shù)據(jù)不一致。

  • 因為內(nèi)存斷電就清空數(shù)據(jù),存放到內(nèi)存中的數(shù)據(jù)可能丟失。

二、Redis 概念知識

1、什么是 Redis

Redis 是一個高性能的 Key-Value 數(shù)據(jù)庫,它是完全開源免費的,而且 Redis 是一個 NOSQL 類型數(shù)據(jù)庫,是為了解決 高并發(fā)、高擴(kuò)展,大數(shù)據(jù)存儲 等一系列的問題而產(chǎn)生的數(shù)據(jù)庫解決方案,是一個非關(guān)系型的數(shù)據(jù)庫。但是,它也是不能替代關(guān)系型數(shù)據(jù)庫,只能作為特定環(huán)境下的擴(kuò)充。

2、為什么使用 Redis 作為緩存

  • 支持高可用:Redis 支持 master\slave 主\從機(jī)制、sentinal 哨兵模式、cluster 集群模式,這樣大大保證了 Redis 運行的穩(wěn)定和高可用行。

  • 支持多種數(shù)據(jù)結(jié)構(gòu):Redis 不僅僅支持簡單的 Key/Value 類型的數(shù)據(jù),同時還提供 list、set、zset、hash 等數(shù)據(jù)結(jié)構(gòu)的存儲。

  • 支持?jǐn)?shù)據(jù)持久化:可以將內(nèi)存中的數(shù)據(jù)持久化在磁盤中,當(dāng)宕機(jī)或者故障重啟時,可以再次加載進(jìn)如 Redis,從而不會或減少數(shù)據(jù)的丟失。

  • 有很多工具與插件對其支持:Redis 已經(jīng)在業(yè)界廣泛使用,已經(jīng)是成為緩存的首選目標(biāo),所以很多語言和工具對其支持,我們只需要簡單的操作就可以輕松使用。

SpringBoot用Redis實現(xiàn)數(shù)據(jù)緩存

3、Redis 支持的數(shù)據(jù)類型

Redis 支持的數(shù)據(jù)結(jié)構(gòu)類型包括:

  • 字符串(string)

  • 哈希表(hash)

  • 列表(list)

  • 集合(set)

  • 有序集合(zset)

為了保證讀取的效率,Redis 把數(shù)據(jù)對象都存儲在內(nèi)存當(dāng)中,它可以支持周期性的把更新的數(shù)據(jù)寫入磁盤文件中。而且它還提供了交集和并集,以及一些不同方式排序的操作。

三、緩存后可能遇見的問題

1、緩存穿透

SpringBoot用Redis實現(xiàn)數(shù)據(jù)緩存

緩存穿透:指查詢一個一定不存在的數(shù)據(jù),由于緩存是不命中時需要從數(shù)據(jù)庫查詢,查不到數(shù)據(jù)則不寫入緩存,這將導(dǎo)致這個不存在的數(shù)據(jù)每次請求都要到數(shù)據(jù)庫去查詢,造成緩存穿透。

緩存穿透幾種解決辦法:

  • 緩存空值,在從 DB 查詢對象為空時,也要將空值存入緩存,具體的值需要使用特殊的標(biāo)識, 能和真正緩存的數(shù)據(jù)區(qū)分開,另外將其過期時間設(shè)為較短時間。

  • 使用布隆過濾器,布隆過濾器能判斷一個 key 一定不存在(不保證一定存在,因為布隆過濾器結(jié)構(gòu)原因,不能刪除,但是舊值可能被新值替換,而將舊值刪除后它可能依舊判斷其可能存在),在緩存的基礎(chǔ)上,構(gòu)建布隆過濾器數(shù)據(jù)結(jié)構(gòu),在布隆過濾器中存儲對應(yīng)的 key,如果存在,則說明 key 對應(yīng)的值為空。

2、緩存擊穿

SpringBoot用Redis實現(xiàn)數(shù)據(jù)緩存

緩存擊穿:某個 key 非常熱點,訪問非常頻繁,處于集中式高并發(fā)訪問的情況,當(dāng)這個 key 在失效的瞬間,大量的請求就擊穿了緩存,直接請求數(shù)據(jù)庫,就像是在一道屏障上鑿開了一個洞。

緩存擊穿幾種解決辦法:

  • 設(shè)置二級緩存,或者設(shè)置熱點緩存永不過期,需要根據(jù)實際情況進(jìn)行配置。

  • 使用互斥鎖,在執(zhí)行過程中,如果緩存過期,那么先獲取分布式鎖,在執(zhí)行從數(shù)據(jù)庫中加載數(shù)據(jù),如果找到數(shù)據(jù)就存入緩存,沒有就繼續(xù)該有的動作,在這個過程中能保證只有一個線程操作數(shù)據(jù)庫,避免了對數(shù)據(jù)庫的大量請求。

3、緩存雪崩

SpringBoot用Redis實現(xiàn)數(shù)據(jù)緩存

緩存雪崩:當(dāng)緩存服務(wù)器重啟、或者大量緩存集中在某一個時間段失效,這樣在失效的時候,也會給后端系統(tǒng)(比如DB)帶來很大壓力,造成數(shù)據(jù)庫后端故障,從而引起應(yīng)用服務(wù)器雪崩。

緩存雪崩幾種解決辦法:

  • 緩存組件設(shè)計高可用,緩存高可用是指,存儲緩存的組件的高可用,能夠防止單點故障、機(jī)器故障、機(jī)房宕機(jī)等一系列問題。例如 Redis sentinel 和 Redis Cluster,都實現(xiàn)了高可用。

  • 請求限流與服務(wù)熔斷降級機(jī)制,限制服務(wù)請求次數(shù),當(dāng)服務(wù)不可用時快速熔斷降級。

  • 設(shè)置緩存過期時間一定的隨機(jī)分布,避免集中在同一時間緩存失效。

  • 定時更新緩存策略,對于實時性要求不高的數(shù)據(jù),定時進(jìn)行更新。

4、緩存一致性

使用緩存很大可能導(dǎo)致數(shù)據(jù)不一致問題,如下:

  • 更熟數(shù)據(jù)庫成功 -> 更新緩存失敗 -> 數(shù)據(jù)不一致

  • 更新緩存成功 -> 更新數(shù)據(jù)庫失敗 -> 數(shù)據(jù)不一致

  • 更新數(shù)據(jù)庫成功 -> 淘汰緩存失敗 -> 數(shù)據(jù)不一致

  • 淘汰緩存成功 -> 更新數(shù)據(jù)庫失敗 -> 查詢緩存mis

所以使用緩存時候,應(yīng)該結(jié)合實際情況,考慮緩存的數(shù)據(jù)是否有一致性需求。

四、SpringBoot 如何結(jié)合 Redis 實現(xiàn)緩存

1、Mavne 引入相關(guān)依賴

  • spring-boot-starter-data-redis

  • commons-pool2

SpringBoot用Redis實現(xiàn)數(shù)據(jù)緩存

2、配置 Redis 參數(shù)

application 文件中添加連接 Redis 的配置參數(shù)

Redis 單機(jī)配置:

SpringBoot用Redis實現(xiàn)數(shù)據(jù)緩存

Redis 哨兵配置:

SpringBoot用Redis實現(xiàn)數(shù)據(jù)緩存

Redis 集群配置:

SpringBoot用Redis實現(xiàn)數(shù)據(jù)緩存

3、配置 Spring 緩存管理器

@Configuration
public class RedisConfig {

    /**
     * 配置緩存管理器
     * @param factory Redis 線程安全連接工廠
     * @return 緩存管理器
     */
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        // 生成兩套默認(rèn)配置,通過 Config 對象即可對緩存進(jìn)行自定義配置
        RedisCacheConfiguration cacheConfig = RedisCacheConfiguration.defaultCacheConfig()
                // 設(shè)置過期時間 10 分鐘
                .entryTtl(Duration.ofMinutes(10))
                // 設(shè)置緩存前綴
                .prefixKeysWith("cache:user:")
                // 禁止緩存 null 值
                .disableCachingNullValues()
                // 設(shè)置 key 序列化
                .serializeKeysWith(keyPair())
                // 設(shè)置 value 序列化
                .serializeValuesWith(valuePair());
        // 返回 Redis 緩存管理器
        return RedisCacheManager.builder(factory)
                            .withCacheConfiguration("user", cacheConfig).build();
    }

    /**
     * 配置鍵序列化
     * @return StringRedisSerializer
     */
    private RedisSerializationContext.SerializationPair keyPair() {
        return RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer());
    }

    /**
     * 配置值序列化,使用 GenericJackson2JsonRedisSerializer 替換默認(rèn)序列化
     * @return GenericJackson2JsonRedisSerializer
     */
    private RedisSerializationContext.SerializationPair valuePair() {
        return RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer());
    }

}

4、服務(wù)中使用 SpringCache 的注解

@Service
@CacheConfig(cacheNames = "user")
public class UserServiceImpl implements UserService {

    /**
     * 新增用戶
     */
    public User addUser(User user) {
        ......
    }

    /**
     * 查詢用戶 
     */
    @Cacheable(key = "#username")
    public User getUserByUsername(String username) {
        ......
    }

    /**
     * 更新用戶 
     */
    @CachePut(key = "#user.username")
    public User updateUser(User user) {
        ......
    }
    
    /**
     * 刪除用戶 
     */
    @CacheEvict(key = "#username")
    public void deleteByUsername(String username) {
        ......
    }

}

注解說明:

  • @CacheConfig:一般配置在類上,指定緩存名稱,這個名稱是和上面“置緩存管理器”中緩存名稱的一致。

  • @Cacheable:作用于方法上,用于對于方法返回結(jié)果進(jìn)行緩存,如果已經(jīng)存在該緩存,則直接從緩存中獲取,緩存的key可以從入?yún)⒅兄付ǎ彺娴?value 為方法返回值。

  • @CachePut:作用于方法上,無論是否存在該緩存,每次都會重新添加緩存,緩存的key可以從入?yún)⒅兄付?,緩存的value為方法返回值,常用作于更新。

  • @CacheEvict:作用于方法上,用于清除緩存

  • @Caching:作用于方法上,用于一次性設(shè)置多個緩存。

上面注解中的常用配置參數(shù):

  • value:緩存管理器中配置的緩存的名稱,這里可以理解為一個組的概念,緩存管理器中可以有多套緩存配置,每套都有一個名稱,類似于組名,這個可以配置這個值,選擇使用哪個緩存的名稱,配置后就會應(yīng)用那個緩存名稱對應(yīng)的配置。

  • key:緩存的 key,可以為空,如果指定要按照 SpEL 表達(dá)式編寫,如果不指定,則缺省按照方法的所有參數(shù)進(jìn)行組合。

  • condition:緩存的條件,可以為空,使用 SpEL 編寫,返回 true 或者 false,只有為 true 才進(jìn)行緩存。

  • unless:不緩存的條件,和 condition 一樣,也是 SpEL 編寫,返回 true 或者 false,為 true 時則不進(jìn)行緩存。

5、啟動類添加開啟緩存注解

SpringBoot用Redis實現(xiàn)數(shù)據(jù)緩存

  • @EnableCaching:作用于類上,用于開啟注解功能。

五、SpringCache 操作緩存的不足

使用 Spring Cache 雖然方便,但是也有很多局限性,因為它多是根據(jù)請求參數(shù)命名 key,根據(jù)返回指設(shè)置 value,這樣很多情況下,我們想方法內(nèi)部進(jìn)行命名和操作有一定的限制。如果我們需要靈活設(shè)置緩存,可以不用 SpringCache 提供的注解,直接在代碼中使用 Spring-data-redis 包提供的方法,手動操作 key 與 value。

  • opsForValue().set(String key, String value);

  • opsForValue().get(String key);

SpringBoot用Redis實現(xiàn)數(shù)據(jù)緩存

還有經(jīng)常要批量設(shè)置、讀取緩存,可以使用:

  • opsForValue().multiSet(Map map);

  • opsForValue().multiGet(List list);

SpringBoot用Redis實現(xiàn)數(shù)據(jù)緩存

六、SpringBoot + SpringCache + Redis 示例項目

下面是一個簡單的 SpringBoot 項目,用于對用戶的增刪改查,這里使用 SpringCache 來模擬對數(shù)據(jù)進(jìn)行緩存,示例如下:

1、Mavne 引入相關(guān)依賴

Maven 中引入 SpringBoot 和 Redis 依賴,因為使用了



    4.0.0

    
        org.springframework.boot
        spring-boot-starter-parent
        2.2.2.RELEASE
    

    mydlq.club
    springboot-redis-example
    0.0.1
    springboot-redis-example
    Demo project for Spring Boot Redis

    
        1.8
    

    
        
            org.springframework.boot
            spring-boot-starter-web
        
        
            org.springframework.boot
            spring-boot-starter-data-redis
        
        
            org.apache.commons
            commons-pool2
        
        
            org.projectlombok
            lombok
        
    

    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
            
        
    

2、配置連接 Redis 參數(shù)

SpringBoot用Redis實現(xiàn)數(shù)據(jù)緩存

3、配置 Spring 緩存管理器

緩存配置類,里面配置緩存管理器,配置緩存的全局過期時間、序列化等參數(shù)。

import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.serializer.*;
import java.time.Duration;

/**
 * Redis 配置類
 */
@Configuration
public class RedisConfig {

    /**
     * 配置緩存管理器
     * @param factory Redis 線程安全連接工廠
     * @return 緩存管理器
     */
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        // 生成兩套默認(rèn)配置,通過 Config 對象即可對緩存進(jìn)行自定義配置
        RedisCacheConfiguration cacheConfig1 = RedisCacheConfiguration.defaultCacheConfig()
                // 設(shè)置過期時間 10 分鐘
                .entryTtl(Duration.ofMinutes(10))
                // 設(shè)置緩存前綴
                .prefixKeysWith("cache:user:")
                // 禁止緩存 null 值
                .disableCachingNullValues()
                // 設(shè)置 key 序列化
                .serializeKeysWith(keyPair())
                // 設(shè)置 value 序列化
                .serializeValuesWith(valuePair());
        RedisCacheConfiguration cacheConfig2 = RedisCacheConfiguration.defaultCacheConfig()
                // 設(shè)置過期時間 30 秒
                .entryTtl(Duration.ofSeconds(30))
                .prefixKeysWith("cache:user_info:")
                .disableCachingNullValues()
                .serializeKeysWith(keyPair())
                .serializeValuesWith(valuePair());
        // 返回 Redis 緩存管理器
        return RedisCacheManager.builder(factory)
                .withCacheConfiguration("user", cacheConfig1)
                .withCacheConfiguration("userInfo", cacheConfig2)
                .build();
    }

    /**
     * 配置鍵序列化
     * @return StringRedisSerializer
     */
    private RedisSerializationContext.SerializationPair keyPair() {
        return RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer());
    }

    /**
     * 配置值序列化,使用 GenericJackson2JsonRedisSerializer 替換默認(rèn)序列化
     * @return GenericJackson2JsonRedisSerializer
     */
    private RedisSerializationContext.SerializationPair valuePair() {
        return RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer());
    }

}

4、定義實體類

用戶實體類

User

SpringBoot用Redis實現(xiàn)數(shù)據(jù)緩存

用戶信息實體類

UserInfo

SpringBoot用Redis實現(xiàn)數(shù)據(jù)緩存

5、定義服務(wù)接口

UserService

import mydlq.club.example.entity.User;

/**
 * 用戶業(yè)務(wù)接口
 */
public interface UserService {

    /**
     * 增加賬戶
     *
     * @param user 賬戶
     */
    void addUser(User user);

    /**
     * 獲取賬戶
     *
     * @param username 用戶名
     * @return 用戶信息
     */
    User getUserByUsername(String username);

    /**
     * 修改賬戶
     *
     * @param user 用戶信息
     * @return 用戶信息
     */
    User updateUser(User user);

    /**
     * 刪除賬戶
     * @param username 用戶名
     */
    void deleteByUsername(String username);

}

UserInfoService

import mydlq.club.example.entity.UserInfo;

/**
 * 用戶信息業(yè)務(wù)接口
 */
public interface UserInfoService {

    /**
     * 增加用戶信息
     *
     * @param userInfo 用戶信息
     */
    void addUserInfo(UserInfo userInfo);

    /**
     * 獲取用戶信息
     *
     * @param name 姓名
     * @return 用戶信息
     */
    UserInfo getByName(String name);

    /**
     * 修改用戶信息
     *
     * @param userInfo 用戶信息
     * @return 用戶信息
     */
    UserInfo updateUserInfo(UserInfo userInfo);

    /**
     * 刪除用戶信息
     * @param name 姓名
     */
    void deleteByName(String name);

}

6、實現(xiàn)服務(wù)類

實現(xiàn) UserService 與 UserInfoService 接口中的方法,里面使用 @Cacheable、@CachePut、@CacheEvict 三個注解完成對用戶與用戶信息數(shù)據(jù)的緩存。

UserServiceImpl(用戶業(yè)務(wù)實現(xiàn)類)

注意,為了演示方便,沒有連接數(shù)據(jù)庫,臨時創(chuàng)建了個成員變量 userMap 來模擬數(shù)據(jù)庫存儲。

import mydlq.club.example.entity.User;
import mydlq.club.example.service.UserService;
import org.springframework.beans.BeanUtils;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import java.util.HashMap;

@Service
@CacheConfig(cacheNames = "user")
public class UserServiceImpl implements UserService {

    private HashMap userMap = new HashMap<>();

    @Override
    public void addUser(User user) {
        userMap.put(user.getUsername(), user);
    }

    @Override
    @Cacheable(key = "#username",unless = "#result==null ")
    public User getUserByUsername(String username) {
        if (!userMap.containsKey(username)) {
            return null;
        }
        return userMap.get(username);
    }

    @Override
    @CachePut(key = "#user.username")
    public User updateUser(User user) {
        if (!userMap.containsKey(user.getUsername())){
            throw new RuntimeException("不存在該用戶");
        }
        // 獲取存儲的對象
        User newUser = userMap.get(user.getUsername());
        // 復(fù)制要更新的數(shù)據(jù)到新對象,因為不能更改用戶名信息,所以忽略
        BeanUtils.copyProperties(user, newUser, "username");
        // 將新的對象存儲,更新舊對象信息
        userMap.put(newUser.getUsername(), newUser);
        // 返回新對象信息
        return newUser;
    }

    @Override
    @CacheEvict(key = "#username")
    public void deleteByUsername(String username) {
        userMap.remove(username);
    }

}

UserInfoServiceImpl(用戶信息業(yè)務(wù)實現(xiàn))

注意,為了演示方便,沒有連接數(shù)據(jù)庫,臨時創(chuàng)建了個成員變量 userInfoMap 來模擬數(shù)據(jù)庫存儲。

import mydlq.club.example.entity.UserInfo;
import mydlq.club.example.service.UserInfoService;
import org.springframework.beans.BeanUtils;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import java.util.HashMap;

@Service
@CacheConfig(cacheNames = "userInfo")
public class UserInfoServiceImpl implements UserInfoService {

    private HashMap userInfoMap = new HashMap<>();

    @Override
    public void addUserInfo(UserInfo userInfo) {
        userInfoMap.put(userInfo.getName(), userInfo);
    }

    @Override
    @Cacheable(key = "#name", unless = "#result==null")
    public UserInfo getByName(String name) {
        if (!userInfoMap.containsKey(name)) {
            return null;
        }
        return userInfoMap.get(name);
    }

    @Override
    @CachePut(key = "#userInfo.name")
    public UserInfo updateUserInfo(UserInfo userInfo) {
        if (!userInfoMap.containsKey(userInfo.getName())) {
            throw new RuntimeException("該用戶信息沒有找到");
        }
        // 獲取存儲的對象
        UserInfo newUserInfo = userInfoMap.get(userInfo.getName());
        // 復(fù)制要更新的數(shù)據(jù)到新對象,因為不能更改用戶名信息,所以忽略
        BeanUtils.copyProperties(userInfo, newUserInfo, "name");
        // 將新的對象存儲,更新舊對象信息
        userInfoMap.put(newUserInfo.getName(), newUserInfo);
        // 返回新對象信息
        return newUserInfo;
    }

    @Override
    @CacheEvict(key = "#name")
    public void deleteByName(String name) {
        userInfoMap.remove(name);
    }

}

7、創(chuàng)建 Controller

UserController

import mydlq.club.example.entity.User;
import mydlq.club.example.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

/**
 * 用戶 Controller
 */
@RestController
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("/user/{username}")
    public User getUser(@PathVariable String username) {
        return userService.getUserByUsername(username);
    }

    @PostMapping("/user")
    public String createUser(@RequestBody User user) {
        userService.addUser(user);
        return "SUCCESS";
    }

    @PutMapping("/user")
    public User updateUser(@RequestBody User user) {
        return userService.updateUser(user);
    }

    @DeleteMapping("/user/{username}")
    public String deleteUser(@PathVariable String username) {
        userService.deleteByUsername(username);
        return "SUCCESS";
    }

}

UserInfoController

import mydlq.club.example.entity.UserInfo;
import mydlq.club.example.service.UserInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

/**
 * 用戶信息 Controller
 */
@RestController
public class UserInfoController {

    @Autowired
    private UserInfoService userInfoService;

    @GetMapping("/userInfo/{name}")
    public UserInfo getUserInfo(@PathVariable String name) {
        return userInfoService.getByName(name);
    }

    @PostMapping("/userInfo")
    public String createUserInfo(@RequestBody UserInfo userInfo) {
        userInfoService.addUserInfo(userInfo);
        return "SUCCESS";
    }

    @PutMapping("/userInfo")
    public UserInfo updateUserInfo(@RequestBody UserInfo userInfo) {
        return userInfoService.updateUserInfo(userInfo);
    }

    @DeleteMapping("/userInfo/{name}")
    public String deleteUserInfo(@PathVariable String name) {
        userInfoService.deleteByName(name);
        return "SUCCESS";
    }

}

8、啟動類

啟動類中添加 @EnableCaching 注解開啟緩存。

SpringBoot用Redis實現(xiàn)數(shù)據(jù)緩存

感謝各位的閱讀,以上就是“SpringBoot用Redis實現(xiàn)數(shù)據(jù)緩存”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對SpringBoot用Redis實現(xiàn)數(shù)據(jù)緩存這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!


網(wǎng)頁題目:SpringBoot用Redis實現(xiàn)數(shù)據(jù)緩存
網(wǎng)站地址:http://weahome.cn/article/jdjpgp.html

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部