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

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;

@Configuration

public class RedisTemplateConfig  {


    // 工具   redisTemplate
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        // 创建一个redisTemplate
        RedisTemplate<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和public
        om.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 {


    @Autowired
    private RedisTemplate redisTemplate;


    @Test
    public 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
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        // 创建一个redisTemplate
        RedisTemplate<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和public
        om.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
    @Bean
    public 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的缓存


http://www.kler.cn/news/308965.html

相关文章:

  • 二十种编程语言庆祝中秋节
  • CesiumJS+SuperMap3D.js混用实现通视分析
  • SprinBoot+Vue基于推荐算法的智能书店的设计与实现
  • 车载软件架构 --- SOA设计与应用(下)
  • grafana升级指南
  • vue table id一样的列合并
  • 深度学习和机器学习的区别
  • linux-安全管理-用户认证
  • leetcode 345.翻转字符串中的元音字母
  • 浅谈住房城乡建设部科技创新平台布局重点方向
  • 代码随想录Day 48|单调栈,leetcode题目:739. 每日温度、496.下一个更大元素 I、503.下一个更大元素II
  • Reactive 编程-Vert.x
  • 云原生(Cloud Native)简介及相关技术
  • 3分钟了解 跨网文件安全交换的最佳方案是什么
  • nano在shell编程中的作用
  • LLM Prompt
  • wordpress源码资源站整站打包32GB数据,含6.7W条资源数据
  • Python元组详解
  • Linux:RPM软件包管理以及yum软件包仓库
  • 工业园生活污水处理设备产地货源
  • 提问即创作:用Prompt提示词引领AI灵感爆发
  • 云原生(Cloud Native)
  • PHP安全
  • JSON 数据 Excel 行转列
  • Gradio导入AIGC大模型创建web端智能体聊天机器人,python(2)
  • Matlab simulink建模与仿真 第十三章(信号通路库)
  • TinyML-On-The-Fly: 实时、低功耗、低成本的微控制器嵌入式设备内计算机视觉技术用于无人机图像分类
  • AtCoder ABC370 A-D题解
  • 传知代码-KAN卷积:医学图像分割新前沿
  • 使用Pydantic模型和LangChain构建高效查询过滤器