SpringBoot整合Redis缓存管理

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=UTCusername: rootpassword: 123jpa:# 显示使用JPA进行数据库查询的SQL语句show-sql: trueredis:host: 192.168.48.67port: 6379password:
开启缓存机制
@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;@Servicepublic class CommentService {@Autowiredprivate CommentRepository commentRepository;@Autowiredprivate 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的序列化方式为JSONtemplate.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.hqwc.cn/news/1923.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java安全——应用安全

Java安全 Java 应用安全 JCE&#xff08;Java Cryptography Extension&#xff09;java加密扩展包 Java Cryptography Extension&#xff08;JCE&#xff09;是一个可选的Java标准扩展&#xff0c;提供了一组用于加密、密钥生成和密钥协商等功能的类和接口。JCE包含了导入、生…

android checkBox的使用

一、前言&#xff1a;之前工作中遇到的checkbox的使用是左边一个复选框&#xff0c;右边一个text。系统学完之后发现那样做的话有点别扭&#xff0c;还是中规中矩的舒坦。记录一下学习经过。 二、代码展示&#xff1a; 1.使用系统自带的checkbox插件。 创建一个CheckBoxActiv…

Solr框架 01 Solr框架简介,安装,配置(Analysis,Dataimport)

Solr简介&#xff1a; Solr是一个高性能&#xff0c;基于Lucene的全文搜索服务器。同时对其进行了扩展&#xff0c;提供了比Lucene更为丰富的查询语言&#xff0c;同时实现了可配置、可扩展&#xff0c;并对查询性能进行了优化&#xff0c;并且提供了一个完善的功能管理界面&am…

CentOs中文件权限命令

文件权限&#xff1a; ls -l命令查看文件详情&#xff0c;前十位就是文件的类型和权限 第一位&#xff1a;类型&#xff1a; - 普通文件 d 目录 l 链接文件&#xff08;快捷方式&#xff09;link 2~4位&#xff1a;所有者的权限 5~7位&#xff1a;所有者所在组其它用户的权限 …

2021 年高教社杯全国大学生数学建模竞赛 E 题 中药材的鉴别 第一题

目录 1.数据预处理 1.1 数据基本信息探索 1.2 数据可视化 1.3 异常值处理 2. 数据特征值提取 2.1 数据标准化 2.2 PCA提取特征值 3. 数据聚类鉴别药材种类 3.1 肘部图确定K值 3.2 轮廓系数图确定K值 3.3 数据聚类 3.4 聚类结果可视化 4. 研究不同种类药材…

【案例实战】SpringBoot整合Redis实现缓存分页数据查询

正式观看本文之前&#xff0c;设想一个问题&#xff0c;高并发情况下&#xff0c;首页列表数据怎么做&#xff1f; 类似淘宝首页&#xff0c;这些商品是从数据库中查出来的吗&#xff1f;答案肯定不是&#xff0c;在高并发的情况下&#xff0c;数据库是扛不住的&#xff0c;那么…

Redis分布式问题

Redis实现分布式锁 Redis为单进程单线程模式&#xff0c;采用队列模式将并发访问变成串行访问&#xff0c;且多客户端对Redis的连接并不存在竞争关系Redis中可以使用SETNX命令实现分布式锁。当且仅当 key 不存在&#xff0c;将 key 的值设为 value。 若给定的 key 已经存在&…

『赠书活动 | 第十三期』《算力经济:从超级计算到云计算》

&#x1f497;wei_shuo的个人主页 &#x1f4ab;wei_shuo的学习社区 &#x1f310;Hello World &#xff01; 『赠书活动 &#xff5c; 第十三期』 本期书籍&#xff1a;《算力经济&#xff1a;从超级计算到云计算》 赠书规则&#xff1a;评论区&#xff1a;点赞&#xff5c;收…

全志V3S嵌入式驱动开发(开发环境再升级)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 前面我们陆陆续续开发了差不多有10个驱动&#xff0c;涉及到网口、串口、音频和视频等几个方面。但是整个开发的效率还是比较低的。每次开发调试的…

Matlab论文插图绘制模板第105期—带缺口的分组填充箱线图

在之前的文章中&#xff0c;分享了Matlab带缺口的分组箱线图的绘制模板&#xff1a; 进一步&#xff0c;再来分享一下带缺口的分组填充箱线图的绘制模板。 先来看一下成品效果&#xff1a; 特别提示&#xff1a;本期内容『数据代码』已上传资源群中&#xff0c;加群的朋友请自…

筹码分布图高级用法——历史换手衰减系数自动计算公式

在使用筹码分布图时&#xff0c;很多人习惯于采用软件的默认设置&#xff0c;然而默认设置不一定能满足我们的要求。今天将向大家介绍筹码分布图的高级用法——历史换手衰减系数&#xff0c;并编写历史换手衰减系数自动计算公式。有些网友认为通过修改衰减系数&#xff0c;可以…

【C++实现二叉树的遍历】

目录 一、二叉树的结构二、二叉树的遍历方式三、源码 一、二叉树的结构 二、二叉树的遍历方式 先序遍历&#xff1a; 根–>左–>右中序遍历&#xff1a; 左–>根–>右后序遍历&#xff1a;左–>右–>根层次遍历&#xff1a;顶层–>底层 三、源码 注&am…