SpringBoot整合Redis缓存管理

news2024/9/9 4:44:55
1. 添加 Spring Data Redis 依赖启动器。在 chapter06 项目的 pom.xml 文件中添加 Spring Data Redis 依赖 启动器。
<!-- 引入整合 Redis 缓存的依赖启动器 -->
<dependency>
<groupId> org.springframework.boot </groupId>
<artifactId> spring-boot-starter-data-redis </artifactId>
</dependency>
2.Redis 服务连接配置。使用类似 Redis 的第三方缓存组件进行缓存管理时,缓存数据并不是像 Spring
Boot 默认缓存管理那样存储在内存中,而是需要预先搭建类似 Redis 服务的数据仓库进行缓存存储。所
以,这里首先需要安装并启动 Redis 服务;然后在项目的全局配置文件 application.properties 中添加
Redis 服务的连接配置。
# Redis 服务器地址
spring.redis.host = 127.0.0.1
# Redis 服务器连接端口
spring.redis.port = 6379
# Redis 服务器连接密码 ( 默认为空 )
spring.redis.password =
或yml格式
spring:
  # MySQL数据库连接配置
  datasource:
    url: jdbc:mysql://localhost:3306/springbootdata?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=UTC
    username: root
    password: 123
  jpa:
    # 显示使用JPA进行数据库查询的SQL语句
    show-sql: true

  redis:
    host: 192.168.48.67
    port: 6379
    password:
开启缓存机制
@EnableCaching//开启了SpringBoot基于注解的缓存管理实现

 

1 @EnableCaching注解
@EnableCaching 是由 Spring 框架提供的, Spring Boot 框架对该注解进行了继承,该注解需要配置在类
上(在 Spring Boot 中,通常配置在项目启动类上),用于开启基于注解的缓存支持。
2 @Cacheable注解
@Cacheable 注解也是由 Spring 框架提供的,可以作用于类或方法(通常用在数据查询方法上),用于
对方法的查询结果进行缓存存储。 @Cacheable 注解的执行顺序是,先进行缓存查询,如果为空则进行
方法查询,并将结果进行缓存;如果缓存中有数据,不进行方法查询,而是直接使用缓存数据。
Cacheable 注解提供了多个属性,用于对缓存存储进行相关配置,具体属性及说明如下表所示。

 

 

下面我们针对@Cacheable注解的属性进行具体讲解。

1.value/cacheNames属性
value cacheNames 属性作用相同,用于指定缓存的名称空间,可以同时指定多个名称空间(例如
@Cacheable(cacheNames = {"comment1", "comment2"}) )。如果 @Cacheable 注解只配置 value (或
cacheNames )的一个属性,那么这两个属性名可以省略,例如 @Cacheable("comment") 指定了缓存
的名称空间为 comment
2.key属性
key 属性的作用是指定缓存数据对应的唯一标识,默认使用注解标记的方法参数值,也可以使用 SpEL
达式。缓存数据的本质是 Map 类型数据, key 用于指定唯一的标识, value 用于指定缓存的数据。
如果缓存数据时,没有指定 key 属性, Spring Boot 默认提供的配置类 SimpleKeyGenerator 会通过
generateKey(Object...params) 方法参数生成 key 值。默认情况下,如果 generateKey() 方法有一个参
数,参数值就是 key 属性的值;如果 generateKey() 方法没有参数,那么 key 属性是一个空参的
SimpleKey[] 对象;如果有多个参数,那么 key 属性是一个带参的 SimpleKey[params1,[param2,...]]
象。
除了使用默认 key 属性值外,还可以手动指定 key 属性值,或者是使用 Spring 框架提供的 SpEL 表达式。关
于缓存中支持的 SpEL 表达式及说明如下表所示。

 

3.keyGenerator属性
keyGenerator 属性与 key 属性本质作用相同,都是用于指定缓存数据的 key ,只不过 keyGenerator 属性
指定的不是具体的 key 值,而是 key 值的生成器规则,由其中指定的生成器生成具体的 key 。使用时,
keyGenerator 属性与 key 属性要二者选一。关于自定义 key 值生成器的定义,读者可以参考 Spring Boot
默认配置类 SimpleKeyGenerator 的定义方式,这里不做具体说明。
4.cacheManager/cacheResolver属性
cacheManager cacheResolver 属性分别用于指定缓存管理器和缓存解析器,这两个属性也是二选一使
用,默认情况下不需要配置,如果存在多个缓存管理器(如 Redis Ehcache 等)可以使用这两个属性分
别指定。
5.condition属性
condition 属性用于对数据进行有条件的选择性存储,只有当指定条件为 true 时才会对查询结果进行缓
存,可以使用 SpEL 表达式指定属性值。例如
@Cacheable(cacheNames="comment",condition="#comment_id>10") 表示方法参数 comment_id
值大于 10 才会对结果数据进行缓存。
6.unless属性
unless 属性的作用与 condition 属性相反,当指定的条件为 true 时,方法的返回值不会被缓存。 unless
性可以使用 SpEL 表达式指定。 @Cacheable(cacheNames="comment",unless="#result==null") 表示只
有查询结果不为空才会对结果数据进行缓存储。
7.sync属性
sync 属性表示数据缓存过程中是否使用异步模式,默认值为 false

3 @CachePut注解

@CachePut 注解是由 Spring 框架提供的,可以作用于类或方法(通常用在数据更新方法上),该注解的
作用是更新缓存数据。 @CachePut 注解的执行顺序是,先进行方法调用,然后将方法结果更新到缓存
中。
@CachePut 注解也提供了多个属性,这些属性与 @Cacheable 注解的属性完全相同。

4 @CacheEvict注解

@CacheEvict 注解是由 Spring 框架提供的,可以作用于类或方法(通常用在数据删除方法上),该注解
的作用是删除缓存数据。 @CacheEvict 注解的默认执行顺序是,先进行方法调用,然后清除缓存。
@CacheEvict 注解提供了多个属性,这些属性与 @Cacheable 注解的属性基本相同。除此之外,
@CacheEvict 注解额外提供了两个特殊属性 allEntries beforeInvocation ,其说明如下。
1.allEntries属性
allEntries 属性表示是否清除指定缓存空间中的所有缓存数据,默认值为 false (即默认只删除指定 key
应的缓存数据)。例如 @CacheEvict(cacheNames="comment",allEntries= true) 表示方法执行后会删除
缓存空间 comment 中所有的数据。
2.beforeInvocation属性
beforeInvocation 属性表示是否在方法执行之前进行缓存清除,默认值为 false (即默认在执行方法后再
进行领存清除)例如 @CacheEvict(cacheNames="comment",beforeInvocation=true) 表示会在方法执
行之前进行缓存清除。
需要注意的是,如果将 @CacheEvict 注解的 beforeInvocation 属性设置为 true ,会存在一定的弊端。例
如在进行数据删除的方法中发生了异常,这会导致实际数据并没有被删除,但是缓存数据却被提前清除
了。
基于 API Redis 缓存实现

package com.example.demo.service.imp;

import com.example.demo.domain.Comment;
import com.example.demo.repository.CommentRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.*;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.sql.Time;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

@Service

public class CommentService {
    @Autowired
    private CommentRepository commentRepository;
    @Autowired
    private RedisTemplate redisTemplate;
    public Comment findById(int comment_id) {
//通过RedisTemplate查询缓存中的数据(Redis中的数据)
        Object object = redisTemplate.opsForValue().get("comment_" + comment_id);
        if (object !=null){
       return (Comment) object;
   } else {
            Optional<Comment> optional = commentRepository.findById(comment_id);
            Comment comment = new Comment();
            if (optional.isPresent()) {
                comment = optional.get();
            }
            redisTemplate.opsForValue().set("comment_"+comment_id,comment,1,TimeUnit.DAYS);
            return comment;
        }
    }

    public Comment updateComment(Comment comment) {
        commentRepository.updateComment(comment.getAuthor(),
                comment.getArticleId());
        redisTemplate.opsForValue().set("comment_"+comment.getId(),comment);

        return comment;
    }

    public void deleteComment(int comment_id) {
        commentRepository.deleteById(comment_id);
        redisTemplate.delete("comment_"+comment_id);
    }
}

 

 

二.配置以下工具类 解决中文乱码

package com.example.demo.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
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.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.time.Duration;

@Configuration // 定义一个配置类
public class RedisConfig {
 //Api开发
@Bean
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
    RedisTemplate<Object, Object> template = new RedisTemplate();
    //设置Redis模板类工厂
    template.setConnectionFactory(redisConnectionFactory);
    // 使用JSON格式序列化对象,对缓存数据key和value进行转换
    Jackson2JsonRedisSerializer jacksonSerializer = new Jackson2JsonRedisSerializer(Object.class);
    // 解决查询缓存转换异常的问题
    ObjectMapper om = new ObjectMapper();
    om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
    om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
    jacksonSerializer.setObjectMapper(om);
    // 设置RedisTemplate模板API的序列化方式为JSON
    template.setDefaultSerializer(jacksonSerializer);
    return template;
}

//注解开发
    @Bean //返回值表示一个Redis缓存管理器对象,通过对象来管理和配置基于注解开发缓存的数据进行序列化转化

    public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
// 分别创建String和JSON格式序列化对象,对缓存数据key和value进行转换
        RedisSerializer<String> strSerializer = new StringRedisSerializer();
        Jackson2JsonRedisSerializer jacksonSerializer = new Jackson2JsonRedisSerializer(Object.class);
// 解决查询缓存转换异常的问题
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jacksonSerializer.setObjectMapper(om);
// 定制缓存数据序列化方式及时效
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                        .entryTtl(Duration.ofDays(1)) //配置缓存数据的默认存活时间为1天
                        .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(strSerializer))//指定key进行序列化
                        .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jacksonSerializer))//
                        .disableCachingNullValues();//null值不参与序列化操作
        //创建对象,作为返回值返回
        RedisCacheManager cacheManager = RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(config).build();
        return cacheManager;
    }

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/705291.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【单片机】STM32F103C8T6单片机,OLED 1.3寸 IIC OLED,STM32F103单片机,I2C OLED

文章目录 main.coled.coled.hOLED_Font.h 效果&#xff1a; main.c #include "sys.h" #include "usart.h" #include "OLED.h"int main(void) {NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); /* 设置NVIC中断分组2:2位抢占优…

C/C++图形库EasyX保姆级使用教程(一) Microsoft Visual Studio 2022和EasyX的下载及安装使用

C/C图形库EasyX保姆级使用教程 第一章 Microsoft Visual Studio 2022和EasyX的下载及安装使用 文章目录 C/C图形库EasyX保姆级使用教程前言一、图形库【EasyX】是什么&#xff1f;二、2.EasyX图形库和Microsoft Visual Studio 2022的安装1.Microsoft Visual Studio 2022&#…

详细讲述,人工智能、机器学习、深度学习、神经网络、自然语言处理、AIGC之间的关系...

人工智能&#xff08;Artificial Intelligence&#xff0c;AI&#xff09;是计算机科学中一个庞大的研究领域&#xff0c;旨在为计算机创造类似人类智能的功能&#xff0c;例如学习、推理、解决问题、识别模式、理解自然语言等。AI的核心目标是使计算机能够执行那些通常需要人类…

sql读取数据直接存成pandas

导包 import pymysql import pandas as pd获取mysql链接 def get_db():#打开数据库连接db pymysql.connect(host*.*.*.*,port3306,user "wws",passwd "yourpasswd",db "youdb")return db db get_db()写sql 读数据保存 sql "select…

【技术分享】RK356X Debian/Ubuntu 系统安装Docker

本文基于IDO-SBC3528主板演示Debian/Ubuntu 系统任何安装Docker&#xff0c;方法适用于RK3568全系列产品。 IDO-SBC3528-V1采用RK3568四核64位开发的智能主板&#xff0c;可作为RK3568开发评估板&#xff0c;支持8G大内存&#xff1b;支持PCIE2.0接口&#xff0c;可扩展大容量…

数据结构——直接插入排序与希尔排序(图示+文字详解)

内容包括&#xff1a;排序的代码实现&#xff0c;排序原理详解&#xff0c;代码详解&#xff0c;图示 part 1&#xff1a;直接插入排序 代码实现&#xff1a; void InsertSort(int* a, int n) {int i 0;for (i 0; i < n - 1; i){int end i;int tmp a[i 1];while (en…

【已解决】ubuntu下谷歌浏览器不能上网(而火狐可以上网)

现象&#xff1a;ubuntu18.04安装的谷歌浏览器chrome不能上网(谷歌和百度都不可以)&#xff0c;而火狐可以访问谷歌和百度。 问题解决[参考]&#xff1a;将HTTPS Proxy的代理端口号也设为7890就ok了

thinkphp5---安装到宝塔出现Warning: require(): open_basedir错误

centos系统&#xff0c;nginxphp7.3 使用thinkphp5安装到宝塔的linux上&#xff0c;出现以下错误&#xff1a; Warning: require(): open_basedir restriction in effect. File(/www/wwwroot/c 解决办法&#xff1a;找到 php.ini 打开 open_basedir 修改为&#xff1a; /www/…

4.原子操作类:AtomicLong、LongAdderLong、Accumulator

JUC包中有AtomicInteger、AtomicLong和AtomicBoolean等原子性操作类&#xff0c;它们原理类似&#xff0c;下面以AtomicLong为例进行讲解。 AtomicLong 底层的操作自增自减都用Unsafe类中的getAndAddLong方法&#xff08;获取本类内存偏移值&#xff09;实现的&#xff0c;get…

UE4/5数字人Metahuman与Style3D的使用【二、布料模拟】

目录 鼠标点击布料模拟&#xff1a; 让布料模拟可以跟着动画序列&#xff1a; 有穿模情况&#xff1a; 多件衣服替换&#xff1a; 关卡序列中使用缓存&#xff1a; 效果&#xff1a; UE4/5数字人Metahuman与Style3D的使用【一、Style3DAtelier软件制作smd格式衣服并导入ue】…

Apikit 自学日记:保存、使用测试用例

API测试用例是SaaS版本企业版才能使用的功能&#xff0c;免费版用户可通过付费升级后使用。 API管理应用中的测试用例管理涉及到两个场景&#xff1a;单接口测试用例管理 和 多接口测试用例批量测试。 一、单接口测试用例管理 功能入口&#xff1a;API管理应用 / 选中某个项目…

基于Java+SSM+Vue的高校校园点餐系统设计与实现

博主介绍&#xff1a; 大家好&#xff0c;我是一名在Java圈混迹十余年的程序员&#xff0c;精通Java编程语言&#xff0c;同时也熟练掌握微信小程序、Python和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架…

lesson 8下 Zigbee单播通信理论相关概念原理(端点、簇)

目录 Zigbee单播通信理论相关概念原理 端点&#xff08;Endpoint&#xff09; 簇&#xff08;ClusterID&#xff09; 通信数据帧抓包分析 接收过程中的端点和簇&#xff08;接收模块&#xff09; 接收过程中的端点 接收过程中的簇 发送过程中的端点和簇&#xff08;发送…

java适配器模式

一、是什么&#xff1f; 定义: 将一个类的接口变成另外一个类所期待的另一个接口, 从而使因接口不匹配而无法一起工作的两个类能够一起工作 举个例子, 苹果手机想用type-c的充电器充电, 但充电接口不吻合, 所以就选哦一个转接头, 使type-c 能给苹果手机充电, 这就是适配器 …

物联网应用中的 Wi-Fi 6

近年来&#xff0c;设备智联在我们的日常生活中越来越常见。从智能家居设备到工业自动化系统&#xff0c;物联网技术正在改变我们与世界交互的方式。随着物联网设备的不断增多&#xff0c;对可靠、高容量和低功耗无线连接的需求变得尤为迫切。这就是 Wi-Fi 6&#xff08;即 802…

SpringBoot整合Mybatis-plus项目完成CRUD

一、准备阶段&#x1f349; 1.创建项目&#x1f95d; 2.引入依赖&#x1f95d; <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-inst…

2023上半年软考系统分析师科目一整理-24

2023上半年软考系统分析师科目一整理-24 IEEE 802.1x是一种&#xff08; &#xff09;认证协议。 A.用户ID B.报文 C. MAC地址 D. SSID IEEE802.1X协议实现基于端口(MAC地址(的访问控制。认证系统对连接到链路对端的请求者进行认证。一般在用户接入设备上实现802.1X认证。在认证…

【MySQL】利用SQL短路,解决无数据表连接问题

系列文章 MySQL安装教程&#xff08;详细&#xff09; 本文链接&#xff1a;https://blog.csdn.net/youcheng_ge/article/details/126037520 MySQL卸载教程&#xff08;详细&#xff09; 本文链接&#xff1a;https://blog.csdn.net/youcheng_ge/article/details/129279265 …

代理服务器之 squid、lvs、nginx、haproxy之间的区别

代理服务器之 squid、lvs、nginx、haproxy之间的区别 代理服务可简单的分为正向代理和反向代理 1、正向代理 正向代理服务器&#xff1a;squid 用于代理内部网络对 Internet 的连接请求(如 VPN/NAT)&#xff0c;客户端指定代理服务器,并将本来要直接发送给目标 Web 服务器的 HT…

Spring Boot 中的 ElasticsearchRepository 是什么,原理,如何使用

Spring Boot 中的 ElasticsearchRepository 是什么&#xff0c;原理&#xff0c;如何使用 简介 Elasticsearch 是一个开源的分布式搜索和分析引擎&#xff0c;可以通过 RESTful API 进行访问。Spring Data Elasticsearch 是 Spring Data 项目的一部分&#xff0c;提供了与 El…