Heim > Datenbank > Redis > Hauptteil

Wie SpringBoot die Redis-Cache-Implementierung integriert

PHPz
Freigeben: 2023-05-28 10:58:06
nach vorne
708 Leute haben es durchsucht

Von SpringBoot unterstützte Cache-Komponenten

In SpringBoot basiert die Cache-Verwaltung und Speicherung von Daten auf den Cache-bezogenen Cache-Manager-Schnittstellen org.springframework.cache.Cache und org.springframework.cache.CacheManager im Spring-Framework.

Wenn im Programm keine Bean-Komponente vom Typ CacheManager oder ein CacheResolver-Cache-Resolver namens „cacheResolver“ definiert ist, versucht SpringBoot, die folgenden Cache-Komponenten auszuwählen und zu aktivieren (in der angegebenen Reihenfolge):

(1) Generisch

( 2) JCache (JSR-107) (EhCache 3, Hazelcast, Infinispan usw.)

(3) EhCache 2.x

(4) Hazelcast

(5) Infinispan

(6) Couchbase

(7 ) Redis

(8) Koffein

(9) Einfach

Oben werden 9 von SpringBoot unterstützte Cache-Komponenten entsprechend der Ladereihenfolge der SpringBoot-Cache-Komponenten aufgeführt. Nach dem Hinzufügen einer Cache-Verwaltungskomponente (z. B. Redis) zum Projekt. Das SpringBoot-Projekt wählt den entsprechenden Cache-Manager aus und aktiviert ihn. Wenn dem Projekt mehrere Cache-Komponenten gleichzeitig hinzugefügt werden und kein Cache-Manager oder Cache-Resolver (CacheManager oder CacheResolver) angegeben ist, aktiviert SpringBoot die erste der mehreren in der oben genannten Reihenfolge hinzugefügten Cache-Komponenten Cache-Verwaltung (wenn beispielsweise die beiden Cache-Komponenten Couchbase und Redis gleichzeitig hinzugefügt werden, wird zuerst die Couchbase-Komponente aktiviert).

In der im vorherigen Artikel SpringBoot Cache Management (1) Standard-Cache-Verwaltung vorgestellten Standard-Cache-Verwaltung fügte das von uns erstellte Projekt keine Cache-Verwaltungskomponenten hinzu, die Cache-Verwaltung wurde jedoch dennoch implementiert. Dies liegt daran, dass SpringBoot nach dem Einschalten der Cache-Verwaltung in der Reihenfolge der oben genannten Cache-Komponenten nach gültigen Cache-Komponenten sucht. Wenn keine Cache-Komponente vorhanden ist, wird standardmäßig die letzte einfache Cache-Komponente für die Verwaltung verwendet. Die einfache Cache-Komponente ist die Standard-Cache-Verwaltungskomponente von SpringBoot. Sie verwendet standardmäßig ConcurrentMap im Speicher, sodass die Cache-Verwaltung im Speicher weiterhin ohne das Hinzufügen von Cache-Komponenten von Drittanbietern erreicht werden kann . Annotationsbasierte Redis-Cache-ImplementierungStellen Sie die Redis-Cache-Komponente vor, die auf dem von SpringBoot Cache Management (1) Default Cache Management erstellten Projekt basiert, und verwenden Sie annotationsbasierte Methoden, um die spezifische Implementierung der SpringBoot-Integration des Redis-Caches zu erläutern.

(1) Spring Data Redis-Abhängigkeitsstarter hinzufügen

Fügen Sie einen Spring Data Redis-Abhängigkeitsstarter im Pom hinzu. Führen Sie Cache-bezogene automatische Assembly-Klassen aus (zuvor die Standardeinstellung SimpleCacheConfiguration). Der im Container verwendete Cache-Manager wurde in RedisCacheManager geändert. (zuvor der Standard-CacheManager), der von diesem Cache-Manager erstellte Cache ist RedisCache und steuert dann Redis, um Daten zwischenzuspeichern.

(2) Redis-Server-Verbindungskonfiguration

Fügen Sie die Verbindungskonfiguration der Redis-Datenbank in der globalen Konfigurationsdatei application.properties des Projekts hinzu. Der Beispielcode lautet wie folgt:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
Nach dem Login kopieren

(3) Ändern Sie die Methode im CommentService Klasse

Verwenden Sie die Annotationen @ Cacheable, @CachePut und @CacheEvict für die Cache-Verwaltung und führen Sie jeweils Vorgänge wie Cache-Speicherung, Cache-Aktualisierung und Cache-Löschung aus:

# Redis服务器地址
spring.redis.host=127.0.0.1
# Redis服务器连接端口
spring.redis.port=6379
# Redis服务器连接密码(默认为空)
spring.redis.password=
Nach dem Login kopieren

Im obigen Code sind @Cacheable, @ CachePut- und @CacheEvict-Annotationen werden bei der Datenabfrage verwendet. Die Cache-Verwaltung erfolgt für Datenaktualisierungs- und Datenlöschmethoden.

Unter diesen gibt es keinen markierten Schlüsselwert in der @Cacheable-Anmerkung des Abfragecaches, und der Standardparameterwert comment_id wird als Schlüssel zum Speichern von Daten verwendet. Bei der Aktualisierung des Caches muss derselbe Schlüssel verwendet werden Die @Cacheable-Annotation für den Abfragecache, die definiert ist, sofern nicht = „#result==null“ bedeutet, dass das Abfrageergebnis nicht zwischengespeichert wird, wenn es leer ist.

(4) Fügen Sie zwei neue Schnittstellen zur CommentController-Klasse hinzu.

Aktualisierungs- und Löschschnittstellen hinzufügen:

package com.hardy.springbootdatacache.service;

import com.hardy.springbootdatacache.entity.Comment;
import com.hardy.springbootdatacache.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;

/**
 * @Author: HardyYao
 * @Date: 2021/6/19
 */
@Service
public class CommentService {

    @Autowired
    private CommentRepository commentRepository;

    /**
     * 根据评论id查询评论
     * @Cacheable:将该方法的查询结果comment存放在SpringBoot默认缓存中
     * cacheNames:起一个缓存命名空间,对应缓存唯一标识
     * @param id
     * @return
     */
    @Cacheable(cacheNames = "comment", unless = "#result==null")
    public Comment findCommentById(Integer id){
        Optional<Comment> comment = commentRepository.findById(id);
        if(comment.isPresent()){
            Comment comment1 = comment.get();
            return comment1;
        }
        return null;
    }

    /**
     * 更新评论
     * @param comment
     * @return
     */
    @CachePut(cacheNames = "comment",key = "#result.id")
    public Comment updateComment(Comment comment) {
        commentRepository.updateComment(comment.getAuthor(), comment.getaId());
        return comment;
    }

    /**
     * 删除评论
     * @param comment_id
     */
    @CacheEvict(cacheNames = "comment")
    public void deleteComment(int comment_id) {
        commentRepository.deleteById(comment_id);
    }

}
Nach dem Login kopieren

(5) Annotationsbasierter Redis-Abfrage-Cache-Test.

Geben Sie im Browser ein: http://localhost:8080/findCommentById ?id=1 für den Zugriff:

Die Seite hat einen Fehler gemeldet. Überprüfen Sie die Konsoleninformationen:

Wie SpringBoot die Redis-Cache-Implementierung integriert

Laut Fehlermeldung: Die entsprechende SQL-Anweisung wurde beim Abfragen der Benutzerkommentarinformationen ausgeführt Kommentar, aber in An IllegalArgumentException trat während der Cache-Speicherung auf und die Eingabeaufforderung erforderte, dass die entsprechende Kommentar-Entitätsklasse serialisiert werden muss (DefaultSerializer erfordert eine serialisierbare Nutzlast, hat aber ein Objekt vom Typ [com.hardy.springbootdatacache.entity.Comment] empfangen).

(6) Serialisieren Sie das Cache-Objekt

Wie SpringBoot die Redis-Cache-Implementierung integriert

(7) Starten Sie das Projekt neu, um den Abfrage-Cache zu testen

在浏览器中输入:http://localhost:8080/findCommentById?id=1 进行访问(连续访问三次):

Wie SpringBoot die Redis-Cache-Implementierung integriertWie SpringBoot die Redis-Cache-Implementierung integriert

打开Redis客户端可视化工具Redis Desktop Manager,连接本地启用的Redis服务,查看具体的数据缓存效果:

Wie SpringBoot die Redis-Cache-Implementierung integriert

执行findById()方法查询出的用户评论信息Comment正确存储到了Redis缓存库中名为comment的名称空间下。

其中缓存数据的唯一标识key值是以“名称空间comment::+参数值(comment::1)”的字符串形式体现的,而value值则是经过JDK默认序列格式化后的HEX格式存储。这种JDK默认序列格式化后的数据显然不方便缓存数据的可视化查看和管理,所以在实际开发中,通常会自定义数据的序列化格式,这方面的内容在后面会介绍。

(8)基于注解的Redis缓存更新测试

先通过浏览器访问:http://localhost:8080/updateComment?id=1&author=hardy;

接着在访问:http://localhost:8080/findCommentById?id=1,查看浏览器返回信息及控制台打印信息:

Wie SpringBoot die Redis-Cache-Implementierung integriert

Wie SpringBoot die Redis-Cache-Implementierung integriert

Wie SpringBoot die Redis-Cache-Implementierung integriert

可以看到,执行updateComment()更新id为1的数据时执行了一条更新的SQL语句,后续调用findById()方法查询id为1的用户评论信息时没有再次执行查询的SQL语句,且浏览器返回了更新后的正确结果,这说明@CachePut缓存更新配置成功。

(9)基于注解的Redis缓存删除测试

通过浏览器访问:http://localhost:8080/deleteComment?id=1 和 http://localhost:8080/findCommentById?id=1

Wie SpringBoot die Redis-Cache-Implementierung integriert

Wie SpringBoot die Redis-Cache-Implementierung integriert

Wie SpringBoot die Redis-Cache-Implementierung integriert

执行deleteComment()方法删除id为1的数据后查询结果为空,查看Redis缓存数据库:

Wie SpringBoot die Redis-Cache-Implementierung integriert

可以看到之前存储的comment相关数据被删除掉了,这表明@CacheEvict注解缓存删除成功实现。

通过上面的案例可以看出:使用基于注解的Redis缓存实现只需要添加Redis依赖、并使用几个注解在对应的方法上,就可以实现对数据的缓存管理。

另外,还可以在SpringBoot全局配置文件中配置Redis有效期,示例代码如下:

# 对基于注解的Redis缓存数据统一设置有效期为1分钟,单位毫秒
spring.cache.redis.time-to-live=60000
Nach dem Login kopieren

上述代码中,在SpringBoot全局配置文件中添加了“spring.cache.redis.time-to-live”属性统一设置Redis数据的有效期(单位为毫秒),但这种方式不够灵活,因此一般不用。

基于API的Redis缓存实现

在SpringBoot整合Redis缓存实现中,除了基于注解形式的Redis缓存形式外,还有一种开发中更常用的方式——基于API的Redis缓存实现。这种基于API的Redis缓存实现,需要在某种业务需求下通过Redis提供的API调用相关方法实现数据缓存管理。同时,这种方法还可以手动管理缓存的有效期。

下面,通过Redis API的方式讲解SpringBoot整合Redis缓存的具体实现。

(1)使用Redis API进行业务数据缓存管理

在 com.hardy.springbootdatacache.service 包下新建一个 ApiCommentService:

package com.hardy.springbootdatacache.service;

import com.hardy.springbootdatacache.entity.Comment;
import com.hardy.springbootdatacache.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;

/**
 * @Author: HardyYao
 * @Date: 2021/6/19
 */
@Service
public class ApiCommentService {

    @Autowired
    private CommentRepository commentRepository;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 根据评论id查询评论
     * @param id
     * @return
     */
    public Comment findCommentById(Integer id){
        // 先查Redis缓存
        Object o = redisTemplate.opsForValue().get("comment_" + id);
        if (o != null) {
            return (Comment) o;
        } else {
            // 如果缓存中没有,则从数据库查询
            Optional<Comment> dbComment = commentRepository.findById(id);
            if (dbComment.isPresent()) {
                Comment redisComment = dbComment.get();
                // 将查询结果存储到缓存中,并设置有效期为1天
                redisTemplate.opsForValue().set("comment_"+id, redisComment,1, TimeUnit.DAYS);
                return redisComment;
            } else {
                return null;
            }
        }

    }

    /**
     * 更新评论
     * @param comment
     * @return
     */
    public Comment updateComment(Comment comment) {
        commentRepository.updateComment(comment.getAuthor(), comment.getId());
        // 更新数据库数据后进行缓存更新
        redisTemplate.opsForValue().set("comment_" + comment.getId(), comment);
        return comment;
    }

    /**
     * 删除评论
     * @param comment_id
     */
    public void deleteComment(int comment_id) {
        commentRepository.deleteById(comment_id);
        // 删除数据库数据后进行缓存删除
        redisTemplate.delete("comment_" + comment_id);
    }

}
Nach dem Login kopieren

(2)编写Web访问层ApiCommentController

package com.hardy.springbootdatacache.controller;

import com.hardy.springbootdatacache.entity.Comment;
import com.hardy.springbootdatacache.service.ApiCommentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @Author: HardyYao
 * @Date: 2021/6/19
 */
@RestController
@RequestMapping("api")  // 改变请求路径
public class ApiCommentController {

    @Autowired
    private ApiCommentService apiCommentService;

    @RequestMapping(value = "/findCommentById")
    public Comment findCommentById(Integer id){
        Comment comment = apiCommentService.findCommentById(id);
        return comment;
    }

    @RequestMapping(value = "/updateComment")
    public Comment updateComment(Comment comment){
        Comment oldComment = apiCommentService.findCommentById(comment.getId());
        oldComment.setAuthor(comment.getAuthor());
        Comment comment1 = apiCommentService.updateComment(oldComment);
        return comment1;
    }

    @RequestMapping(value = "/deleteComment")
    public void deleteComment(Integer id){
        apiCommentService.deleteComment(id);
    }

}
Nach dem Login kopieren

(3)测试基于API的Redis缓存实现

输入:http://localhost:8080/api/findCommentById?id=2(连续输入三次)、http://localhost:8080/api/updateComment?id=2&author=hardy、http://localhost:8080/deleteComment?id=2进行访问:

Wie SpringBoot die Redis-Cache-Implementierung integriert

Wie SpringBoot die Redis-Cache-Implementierung integriert

Wie SpringBoot die Redis-Cache-Implementierung integriert

Konsolenmeldungen und Redis-Datenbank anzeigen:

Wie SpringBoot die Redis-Cache-Implementierung integriert

Wie SpringBoot die Redis-Cache-Implementierung integriert

Verwandte Konfigurationen für die API-basierte Redis-Cache-Implementierung: Für die API-basierte Redis-Cache-Implementierung ist die Annotation @EnableCaching nicht erforderlich, um annotationsbasiertes Caching zu ermöglichen Unterstützung: Hier können Sie die der Projektstartklasse hinzugefügte Annotation @EnableCaching löschen oder mit Anmerkungen versehen, was sich nicht auf die funktionale Implementierung des Projekts auswirkt.

Das obige ist der detaillierte Inhalt vonWie SpringBoot die Redis-Cache-Implementierung integriert. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:yisu.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!