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

SpringBoot詳解整合Redis緩存方法

 更新時(shí)間:2022年07月15日 10:53:51   作者:悠然予夏  
本文主要介紹了SpringBoot整合Redis緩存的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

1、Spring Boot支持的緩存組件

在Spring Boot中,數(shù)據(jù)的緩存管理存儲(chǔ)依賴于Spring框架中cache相關(guān)的org.springframework.cache.Cache和org.springframework.cache.CacheManager緩存管理器接口。

如果程序中沒(méi)有定義類型為CacheManager的Bean組件或者是名為cacheResolver的CacheResolver緩存解析器,Spring Boot將嘗試選擇并啟用以下緩存組件(按照指定的順序):

(1)Generic

(2)JCache (JSR-107) (EhCache 3、Hazelcast、Infinispan等)

(3)EhCache 2.x

(4)Hazelcast

(5)Infinispan

(6)Couchbase

(7)Redis

(8)Caffeine

(9)Simple

上面按照Spring Boot緩存組件的加載順序,列舉了支持的9種緩存組件,在項(xiàng)目中添加某個(gè)緩存管理組件(例如Redis)后,Spring Boot項(xiàng)目會(huì)選擇并啟用對(duì)應(yīng)的緩存管理器。如果項(xiàng)目中同時(shí)添加了多個(gè)緩存組件,且沒(méi)有指定緩存管理器或者緩存解析器(CacheManager或者cacheResolver),那么Spring Boot會(huì)按照上述順序在添加的多個(gè)緩存中優(yōu)先啟用指定的緩存組件進(jìn)行緩存管理。

剛剛講解的Spring Boot默認(rèn)緩存管理中,沒(méi)有添加任何緩存管理組件能實(shí)現(xiàn)緩存管理。這是因?yàn)殚_(kāi)啟緩存管理后,Spring Boot會(huì)按照上述列表順序查找有效的緩存組件進(jìn)行緩存管理,如果沒(méi)有任何緩存組件,會(huì)默認(rèn)使用最后一個(gè)Simple緩存組件進(jìn)行管理。Simple緩存組件是Spring Boot默認(rèn)的緩存管理組件,它默認(rèn)使用內(nèi)存中的ConcurrentMap進(jìn)行緩存存儲(chǔ),所以在沒(méi)有添加任何第三方緩存組件的情況下,可以實(shí)現(xiàn)內(nèi)存中的緩存管理,但是我們不推薦使用這種緩存管理方式

2、基于注解的Redis緩存實(shí)現(xiàn)

在Spring Boot默認(rèn)緩存管理的基礎(chǔ)上引入Redis緩存組件,使用基于注解的方式講解Spring Boot整合Redis緩存的具體實(shí)現(xiàn)

(1)添加Spring Data Redis依賴啟動(dòng)器。在pom.xml文件中添加Spring Data Redis依賴啟動(dòng)器

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

當(dāng)我們添加進(jìn)redis相關(guān)的啟動(dòng)器之后, SpringBoot會(huì)使用RedisCacheConfigratioin 當(dāng)做生效的自動(dòng)配置類進(jìn)行緩存相關(guān)的自動(dòng)裝配,容器中使用的緩存管理器是RedisCacheManager , 這個(gè)緩存管理器創(chuàng)建的Cache為 RedisCache , 進(jìn)而操控redis進(jìn)行數(shù)據(jù)的緩存

(2)Redis服務(wù)連接配置

# Redis服務(wù)地址
spring.redis.host=127.0.0.1
# Redis服務(wù)器連接端口
spring.redis.port=6379
# Redis服務(wù)器連接密碼(默認(rèn)為空)
spring.redis.password=

(3)對(duì)CommentService類中的方法進(jìn)行修改使用@Cacheable、@CachePut、@CacheEvict三個(gè)注解定制緩存管理,分別進(jìn)行緩存存儲(chǔ)、緩存更新和緩存刪除的演示

package com.lagou.service;
import com.lagou.pojo.Comment;
import com.lagou.repository.CommentRepository;
import org.springframework.beans.factory.annotation.Autowired;
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.Optional;
@Service
public class CommentService {
    @Autowired
    private CommentRepository commentRepository;
    /**
     * @Cacheable: 將該方法查詢結(jié)果comment存放在SpringBoot默認(rèn)緩存中
     * cacheNames: 起一個(gè)緩存的命名空間,對(duì)應(yīng)緩存的唯一標(biāo)識(shí)
     * value:緩存結(jié)果   key:默認(rèn)只有一個(gè)參數(shù)的情況下,key值默認(rèn)就是方法參數(shù)值; 如果沒(méi)有參數(shù)或者多個(gè)參數(shù)的情況:會(huì)使用SimpleKeyGenerate來(lái)為生成key
     */
    @Cacheable(cacheNames = "comment", unless = "#result==null")
    public Comment findCommentById(Integer id) {
        Optional<Comment> byId = commentRepository.findById(id);
        if (byId.isPresent()) {
            Comment comment = byId.get();
            return comment;
        }
        return null;
    }
    // 更新方法
    @CachePut(cacheNames = "comment", key = "#result.id")
    public Comment updateComment(Comment comment) {
        commentRepository.updateComment(comment.getAuthor(), comment.getId());
        return comment;
    }
    // 刪除方法
    @CacheEvict(cacheNames = "comment")
    public void deleteComment(Integer id) {
        commentRepository.deleteById(id);
    }
}

以上 使用@Cacheable、@CachePut、@CacheEvict注解在數(shù)據(jù)查詢、更新和刪除方法上進(jìn)行了緩存管理。

其中,查詢緩存@Cacheable注解中沒(méi)有標(biāo)記key值,將會(huì)使用默認(rèn)參數(shù)值comment_id作為key進(jìn)行數(shù)據(jù)保存,在進(jìn)行緩存更新時(shí)必須使用同樣的key;同時(shí)在查詢緩存@Cacheable注解中,定義了“unless = "#result==null"”表示查詢結(jié)果為空不進(jìn)行緩存

控制層

package com.lagou.controller;
import com.lagou.pojo.Comment;
import com.lagou.service.CommentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class CommentController {
    @Autowired
    private CommentService commentService;
    @RequestMapping( "/findCommentById")
    public Comment findCommentById(Integer id) {
        Comment comment = commentService.findCommentById(id);
        return comment;
    }
    @RequestMapping(value = "/updateComment")
    public Comment updateComment(Comment comment) {
        Comment commentById = commentService.findCommentById(comment.getId());
        commentById.setAuthor(comment.getAuthor());
        return commentService.updateComment(commentById);
    }
    @RequestMapping(value = "/deleteComment")
    public void deleteComment(Integer id) {
        commentService.deleteComment(id);
    }
}

(4) 基于注解的Redis查詢緩存測(cè)試

可以看出,查詢用戶評(píng)論信息Comment時(shí)執(zhí)行了相應(yīng)的SQL語(yǔ)句,但是在進(jìn)行緩存存儲(chǔ)時(shí)出現(xiàn)了IllegalArgumentException非法參數(shù)異常,提示信息要求對(duì)應(yīng)Comment實(shí)體類必須實(shí)現(xiàn)序列化(“DefaultSerializer requires a Serializable payload but received an object of type”)。

(5)將緩存對(duì)象實(shí)現(xiàn)序列化。

(6)再次啟動(dòng)測(cè)試

訪問(wèn)“http://localhost:8080/findCommentById?id=1”查詢id為1的用戶評(píng)論信息,并重復(fù)刷新瀏覽器查詢同一條數(shù)據(jù)信息,查詢結(jié)果

查看控制臺(tái)打印的SQL查詢語(yǔ)句

還可以打開(kāi)Redis客戶端可視化管理工具Redis Desktop Manager連接本地啟用的Redis服務(wù),查看具體的數(shù)據(jù)緩存效果

執(zhí)行findById()方法查詢出的用戶評(píng)論信息Comment正確存儲(chǔ)到了Redis緩存庫(kù)中名為comment的名稱空間下。其中緩存數(shù)據(jù)的唯一標(biāo)識(shí)key值是以“名稱空間comment::+參數(shù)值(comment::1)”的字符串形式體現(xiàn)的,而value值則是經(jīng)過(guò)JDK默認(rèn)序列格式化后的HEX格式存儲(chǔ)。這種JDK默認(rèn)序列格式化后的數(shù)據(jù)顯然不方便緩存數(shù)據(jù)的可視化查看和管理,所以在實(shí)際開(kāi)發(fā)中,通常會(huì)自定義數(shù)據(jù)的序列化格式

(7) 基于注解的Redis緩存更新測(cè)試。

先通過(guò)瀏覽器訪問(wèn)“http://localhost:8080/updateComment/1/shitou”更新id為1的評(píng)論作者名為shitou;

接著,繼續(xù)訪問(wèn)“http://localhost:8080/findCommentById?id=1”查詢id為1的用戶評(píng)論信息

可以看出,執(zhí)行updateComment()方法更新id為1的數(shù)據(jù)時(shí)執(zhí)行了一條更新SQL語(yǔ)句,后續(xù)調(diào)用findById()方法查詢id為1的用戶評(píng)論信息時(shí)沒(méi)有執(zhí)行查詢SQL語(yǔ)句,且瀏覽器正確返回了更新后的結(jié)果,表明@CachePut緩存更新配置成功

(8)基于注解的Redis緩存刪除測(cè)試

通過(guò)瀏覽器訪問(wèn)“http://localhost:8080/deleteComment?id=1”刪除id為1的用戶評(píng)論信息;

執(zhí)行deleteComment()方法刪除id為1的數(shù)據(jù)后查詢結(jié)果為空,之前存儲(chǔ)在Redis數(shù)據(jù)庫(kù)的comment相關(guān)數(shù)據(jù)也被刪除,表明@CacheEvict緩存刪除成功實(shí)現(xiàn)

通過(guò)上面的案例可以看出,使用基于注解的Redis緩存實(shí)現(xiàn)只需要添加Redis依賴并使用幾個(gè)注解可以實(shí)現(xiàn)對(duì)數(shù)據(jù)的緩存管理。另外,還可以在Spring Boot全局配置文件中配置Redis有效期,示例代碼如下:

# 對(duì)基于注解的Redis緩存數(shù)據(jù)統(tǒng)一設(shè)置有效期為1分鐘,單位毫秒
spring.cache.redis.time-to-live=60000

上述代碼中,在Spring Boot全局配置文件中添加了“spring.cache.redis.time-to-live”屬性統(tǒng)一配置Redis數(shù)據(jù)的有效期(單位為毫秒),但這種方式相對(duì)來(lái)說(shuō)不夠靈活

3、基于API的Redis緩存實(shí)現(xiàn)

在Spring Boot整合Redis緩存實(shí)現(xiàn)中,除了基于注解形式的Redis緩存實(shí)現(xiàn)外,還有一種開(kāi)發(fā)中常用的方式——基于API的Redis緩存實(shí)現(xiàn)。這種基于API的Redis緩存實(shí)現(xiàn),需要在某種業(yè)務(wù)需求下通過(guò)Redis提供的API調(diào)用相關(guān)方法實(shí)現(xiàn)數(shù)據(jù)緩存管理;同時(shí),這種方法還可以手動(dòng)管理緩存的有效期。

下面,通過(guò)Redis API的方式講解Spring Boot整合Redis緩存的具體實(shí)現(xiàn)

(1)使用Redis API進(jìn)行業(yè)務(wù)數(shù)據(jù)緩存管理。在com.lagou.service包下編寫(xiě)一個(gè)進(jìn)行業(yè)務(wù)處理的類ApiCommentService

package com.lagou.service;
import com.lagou.pojo.Comment;
import com.lagou.repository.CommentRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
@Service
public class ApiCommentService {
    @Autowired
    private CommentRepository commentRepository;
    @Autowired
    private RedisTemplate redisTemplate;
    // 使用API方式進(jìn)行緩存,先去緩存中查找,緩存中有,直接返回;沒(méi)有查詢數(shù)據(jù)庫(kù)
    public Comment findCommentById(Integer id) {
        Object o = redisTemplate.opsForValue().get("comment_" + id);
        if (o != null) {
            return (Comment) o; // 查詢到數(shù)據(jù)
        } else {
            // 緩存中沒(méi)有,從數(shù)據(jù)庫(kù)中查詢
            Optional<Comment> byId = commentRepository.findById(id);
            if (byId.isPresent()) {
                Comment comment = byId.get();
                // 將查詢結(jié)果存入到緩存中,同時(shí)還可以設(shè)置有效期
                redisTemplate.opsForValue().set("comment_" + id, comment, 1, TimeUnit.DAYS); // 過(guò)期時(shí)間為一天
                return comment;
            }
        }
        return null;
    }
    // 更新方法
    public Comment updateComment(Comment comment) {
        commentRepository.updateComment(comment.getAuthor(), comment.getId());
        // 將更新數(shù)據(jù)進(jìn)行緩存更新
        redisTemplate.opsForValue().set("comment_" + comment.getId(), comment, 1, TimeUnit.DAYS);
        return comment;
    }
    // 刪除方法
    public void deleteComment(Integer id) {
        commentRepository.deleteById(id);
        redisTemplate.delete("comment_" + id);
    }
}

(2)編寫(xiě)Web訪問(wèn)層Controller文件

package com.lagou.controller;
import com.lagou.pojo.Comment;
import com.lagou.service.ApiCommentService;
import com.lagou.service.CommentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api")
public class ApiCommentController {
    @Autowired
    private ApiCommentService commentService;
    @RequestMapping( "/findCommentById")
    public Comment findCommentById(Integer id) {
        Comment comment = commentService.findCommentById(id);
        return comment;
    }
    @RequestMapping(value = "/updateComment")
    public Comment updateComment(Comment comment) {
        Comment commentById = commentService.findCommentById(comment.getId());
        commentById.setAuthor(comment.getAuthor());
        return commentService.updateComment(commentById);
    }
    @RequestMapping(value = "/deleteComment")
    public void deleteComment(Integer id) {
        commentService.deleteComment(id);
    }
}

基于API的Redis緩存實(shí)現(xiàn)的相關(guān)配置。基于API的Redis緩存實(shí)現(xiàn)不需要@EnableCaching注解開(kāi)啟基于注解的緩存支持,所以這里可以選擇將添加在項(xiàng)目啟動(dòng)類上的@EnableCaching進(jìn)行刪除或者注釋

到此這篇關(guān)于SpringBoot詳解整合Redis緩存方法的文章就介紹到這了,更多相關(guān)SpringBoot Redis緩存內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot使用@Scheduled實(shí)現(xiàn)定時(shí)任務(wù)的并行執(zhí)行

    SpringBoot使用@Scheduled實(shí)現(xiàn)定時(shí)任務(wù)的并行執(zhí)行

    在SpringBoot中,如果使用@Scheduled注解來(lái)定義多個(gè)定時(shí)任務(wù),默認(rèn)情況下這些任務(wù)將會(huì)被安排在一個(gè)單線程的調(diào)度器中執(zhí)行,這意味著,這些任務(wù)將會(huì)串行執(zhí)行,而不是并行執(zhí)行,本文介紹了SpringBoot使用@Scheduled實(shí)現(xiàn)定時(shí)任務(wù)的并行執(zhí)行,需要的朋友可以參考下
    2024-06-06
  • JAVA SPI特性及簡(jiǎn)單應(yīng)用代碼實(shí)例

    JAVA SPI特性及簡(jiǎn)單應(yīng)用代碼實(shí)例

    這篇文章主要介紹了JAVA SPI特性及簡(jiǎn)單應(yīng)用代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-05-05
  • java中UDP簡(jiǎn)單聊天程序?qū)嵗a

    java中UDP簡(jiǎn)單聊天程序?qū)嵗a

    這篇文章主要介紹了java中UDP簡(jiǎn)單聊天程序?qū)嵗a,有需要的朋友可以參考一下
    2013-12-12
  • java實(shí)現(xiàn)郵件發(fā)送詳解

    java實(shí)現(xiàn)郵件發(fā)送詳解

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)郵件發(fā)送示例,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-03-03
  • SpringBoot實(shí)現(xiàn)WEB的常用功能案例詳解

    SpringBoot實(shí)現(xiàn)WEB的常用功能案例詳解

    這篇文章主要介紹了SpringBoot實(shí)現(xiàn)WEB的常用功能,本文將對(duì)Spring Boot實(shí)現(xiàn)Web開(kāi)發(fā)中涉及的三大組件Servlet、Filter、Listener以及文件上傳下載功能以及打包部署進(jìn)行實(shí)現(xiàn),需要的朋友可以參考下
    2022-04-04
  • 基于java編寫(xiě)局域網(wǎng)多人聊天室

    基于java編寫(xiě)局域網(wǎng)多人聊天室

    這篇文章主要為大家詳細(xì)介紹了基于java編寫(xiě)局域網(wǎng)多人聊天室的相關(guān)資料,使用socket基于java編寫(xiě)一個(gè)局域網(wǎng)聊天室,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-09-09
  • Java?spring?boot實(shí)現(xiàn)批量刪除功能詳細(xì)示例

    Java?spring?boot實(shí)現(xiàn)批量刪除功能詳細(xì)示例

    這篇文章主要給大家介紹了關(guān)于Java?spring?boot實(shí)現(xiàn)批量刪除功能的相關(guān)資料,文中通過(guò)代碼以及圖文將實(shí)現(xiàn)的方法介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2023-08-08
  • Java中常用時(shí)間的一些相關(guān)方法

    Java中常用時(shí)間的一些相關(guān)方法

    日期的使用多種多樣,但萬(wàn)變不離其宗,下面這篇文章主要給大家介紹了關(guān)于Java中常用時(shí)間的一些相關(guān)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2021-10-10
  • 關(guān)于Jedis的用法以及Jedis使用Redis事務(wù)

    關(guān)于Jedis的用法以及Jedis使用Redis事務(wù)

    這篇文章主要介紹了關(guān)于Jedis的用法以及Jedis使用Redis事務(wù)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • Java判斷List中有無(wú)重復(fù)元素的方法

    Java判斷List中有無(wú)重復(fù)元素的方法

    今天小編就為大家分享一篇Java判斷List中有無(wú)重復(fù)元素的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-07-07

最新評(píng)論

广元市| 浮梁县| 体育| 禄丰县| 西华县| 申扎县| 乐东| 天长市| 洞口县| 长乐市| 乐陵市| 奎屯市| 合肥市| 镇康县| 措美县| 普定县| 平塘县| 雅安市| 资源县| 梅州市| 蓝山县| 崇州市| 阳春市| 宁津县| 马公市| 贵南县| 凌云县| 乳山市| 江阴市| 巴里| 华坪县| 巫山县| 海城市| 横山县| 宜城市| 梅河口市| 都江堰市| 新民市| 金沙县| 朝阳区| 昭平县|