当前位置: 首页 > news >正文

springboot+redis+缓存

整合

添加依赖

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

连接redis,配置yml文件

主机

端口号

数据库是哪一个

密码

配置类

package com.aaa.config;import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
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;@Configurationpublic class RedisTemplateConfig  {// 工具   redisTemplate@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {// 创建一个redisTemplateRedisTemplate<String, Object> template = new RedisTemplate<>();// redis 序列化RedisSerializer<String> redisSerializer = new StringRedisSerializer();// 序列化的对象Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);ObjectMapper om = new ObjectMapper();// 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和publicom.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);// 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会抛出异常om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);jackson2JsonRedisSerializer.setObjectMapper(om);template.setConnectionFactory(factory);//key序列化方式template.setKeySerializer(redisSerializer);//value序列化template.setValueSerializer(jackson2JsonRedisSerializer);//value hashmap序列化template.setHashValueSerializer(jackson2JsonRedisSerializer);return template;}
}

调用类方法进行操作redis

package com.aaa;import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;@SpringBootTest
public class AppTest {@Autowiredprivate RedisTemplate redisTemplate;@Testpublic void testString(){// 添加一个数据redisTemplate.opsForValue().set("test","test1");}}

缓存

我们准备springboot+mybatis来使用缓存

流程

当我们实行增删改查的时候会大量的访问数据库,为了减缓数据库的压力或其他问题,我们使用缓存来解决,如果缓存中没有我们需要的数据时,我们将会访问数据库,但是如果缓存中有我们需要的数据,我们就不用再访问数据库了,而是直接拿到缓存即可

缓存穿透:

业务系统要查询的数据根本就不存在!当业务系统发起查询时,按照上述流程,首先会前往缓存中查询,由于缓存中不存在,然后再前往数据库中查询。由于该数据压根就不存在,因此数据库也返回空。这就是缓存穿透。

  综上所述:业务系统访问压根就不存在的数据,就称为缓存穿透。

危害

  如果存在海量请求查询压根就不存在的数据,那么这些海量请求都会落到数据库中,数据库压力剧增,可能会导致系统崩溃(你要知道,目前业务系统中最脆弱的就是 IO,稍微来点压力它就会崩溃,所以我们要想种种办法保护它)。

解决

把所有可能访问的值全部放到布隆过滤器里面 如果布隆过滤器中没有你要查询的值就直接返回null

缓存击穿:

访问的这个热点数据正好过期了,将会产生大量的请求访问数据库,给数据库带来巨大的压力

解决:

加锁

缓存雪崩:

缓存给数据库抵挡了大量的查询请求,但是一旦缓存宕机了,那么原本被缓存抵挡的海量查询请求就会像疯狗一样涌向数据库。此时数据库如果抵挡不了这巨大的压力,它就会崩溃。

配置类:

package com.aaa.config;import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
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
// 开启缓存
@EnableCaching
public class RedisTemplateConfig  {// 工具   redisTemplate@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {// 创建一个redisTemplateRedisTemplate<String, Object> template = new RedisTemplate<>();// redis 序列化RedisSerializer<String> redisSerializer = new StringRedisSerializer();// 序列化的对象Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);ObjectMapper om = new ObjectMapper();// 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和publicom.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);// 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会抛出异常om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);jackson2JsonRedisSerializer.setObjectMapper(om);template.setConnectionFactory(factory);//key序列化方式template.setKeySerializer(redisSerializer);//value序列化template.setValueSerializer(jackson2JsonRedisSerializer);//value hashmap序列化template.setHashValueSerializer(jackson2JsonRedisSerializer);return template;}// 注入缓存的bean@Beanpublic CacheManager cacheManager(RedisConnectionFactory factory) {RedisSerializer<String> redisSerializer = new StringRedisSerializer();Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
//解决查询缓存转换异常的问题ObjectMapper om = new ObjectMapper();om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);jackson2JsonRedisSerializer.setObjectMapper(om);
// 配置序列化(解决乱码的问题),过期时间600秒RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofSeconds(600)) //.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer)).serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer)).disableCachingNullValues();RedisCacheManager cacheManager = RedisCacheManager.builder(factory).cacheDefaults(config).build();return cacheManager;}
}

开启缓存

@EnableCaching

我们的配置类上面必须要加上这个注解不加 就没有办法使用缓存

缓存一般是加在service层

@Cacheable

对应的value值或者是cachename的值必须要写

查询

用我们的工具就可以看到

如果redis里没有这个数据,它会先访问数据库,然后把我们访问的这个数据添加到缓存里,下次查询的时候因为我们缓存里已经有了我们需要的数据,所以就不会再去访问数据库了,而是直接访问缓存

@CachePut

不管数据里面有没有   都会加到缓存中

添加或修改

我们可以自己去设置缓存的key名

@CacheEvict

删除

清除缓存

@CacheEvict是用来标注在需要清除缓存元素的方法或类上的

allEntries = true:代表清除value对应的值下面的所有的缓存,false:只清楚对应key的缓存

如果不写allEntries:也只会清楚对应key的缓存

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 59.【C语言】内存函数(memmove函数)
  • python爬虫初体验(二)
  • 611. 有效三角形的个数
  • pip install、yum install和conda install三者技术区分
  • Django一分钟:DRF快速实现JWT认证与RBAC权限校验
  • 《程序猿之设计模式实战 · 适配器模式》
  • Vue3中shallowRef和ref区别
  • MySQL篇(事务 - 基础)
  • STL队列
  • 部标(JT/T1078)流媒体对接说明
  • POI操作EXCEL插入图片
  • 两数之和、三数之和、四数之和
  • PTA矩阵转置
  • Vue|插件
  • 2024双11买什么东西比较好?2024双十一好物推荐
  • [case10]使用RSQL实现端到端的动态查询
  • [Vue CLI 3] 配置解析之 css.extract
  • 【159天】尚学堂高琪Java300集视频精华笔记(128)
  • Angularjs之国际化
  • Github访问慢解决办法
  • HTML-表单
  • iOS 颜色设置看我就够了
  • mysql innodb 索引使用指南
  • Transformer-XL: Unleashing the Potential of Attention Models
  • 分类模型——Logistics Regression
  • 七牛云 DV OV EV SSL 证书上线,限时折扣低至 6.75 折!
  • 深度学习入门:10门免费线上课程推荐
  • 腾讯视频格式如何转换成mp4 将下载的qlv文件转换成mp4的方法
  • 网络应用优化——时延与带宽
  • 吴恩达Deep Learning课程练习题参考答案——R语言版
  • 物联网链路协议
  • 新书推荐|Windows黑客编程技术详解
  • 学习笔记:对象,原型和继承(1)
  • 一起来学SpringBoot | 第三篇:SpringBoot日志配置
  • 正则表达式
  • 自定义函数
  • ​软考-高级-系统架构设计师教程(清华第2版)【第9章 软件可靠性基础知识(P320~344)-思维导图】​
  • ​无人机石油管道巡检方案新亮点:灵活准确又高效
  • ‌‌雅诗兰黛、‌‌兰蔻等美妆大品牌的营销策略是什么?
  • # .NET Framework中使用命名管道进行进程间通信
  • #include<初见C语言之指针(5)>
  • #Linux(权限管理)
  • #中的引用型是什么意识_Java中四种引用有什么区别以及应用场景
  • (2)MFC+openGL单文档框架glFrame
  • (2024,RWKV-5/6,RNN,矩阵值注意力状态,数据依赖线性插值,LoRA,多语言分词器)Eagle 和 Finch
  • (C语言版)链表(三)——实现双向链表创建、删除、插入、释放内存等简单操作...
  • (js)循环条件满足时终止循环
  • (Oracle)SQL优化基础(三):看懂执行计划顺序
  • (Redis使用系列) Springboot 实现Redis 同数据源动态切换db 八
  • (补)B+树一些思想
  • (差分)胡桃爱原石
  • (附源码)ssm失物招领系统 毕业设计 182317
  • (五)c52学习之旅-静态数码管
  • (原创)Stanford Machine Learning (by Andrew NG) --- (week 9) Anomaly DetectionRecommender Systems...
  • (转贴)用VML开发工作流设计器 UCML.NET工作流管理系统