Redis的使用场景——热点数据缓存

news2024/9/20 8:07:53

热点数据缓存

Redis的使用场景——热点数据的缓存

1.1 什么是缓存

为了把一些经常访问的数据,放入缓存中以减少对数据库的访问效率,从而减少数据库的压力,提高程序的性能。【在内存中存储】

1.2 缓存的原理

  1. 查询缓存中是否存在对应的数据
  2. 如果缓存中有,即命中,直接返回给程序
  3. 如果没有明中,访问查询数据库
  4. 把查询的数据返回给程序,并同时将查询的数据放入缓存

在这里插入图片描述

1.3 什么样的数据适合放入缓存中

  1. 查询频率高且修改频率低的
  2. 数据安全性低的

1.4 哪个组件可以作为缓存

  1. redis组件
  2. memory组件
  3. ehcache组件等

1.5 java使用redis如何实现缓存

准备

  1. 首先创建一个springboot项目

    在这里插入图片描述

  2. 配置文件

    server.port=端口号
    #数据源
    spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
    spring.datasource.url=jdbc:mysql://localhost:3306/数据库名称?serverTimezone=Asia/Shanghai
    spring.datasource.username=用户名
    spring.datasource.password=密码
    
    #mybatis配置文件
    mybatis.mapper-locations=classpath:mapper/*.xml
    
    #日志
    mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
    
    #redis
    spring.redis.host=IP地址
    spring.redis.port=6379
    spring.redis.database=4
    
  3. 修改mysql依赖,添加mybatis-plus的依赖

    <!--mysql依赖-->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
            </dependency>
            <!--mybatisplus依赖-->
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>3.5.4</version>
            </dependency>
    
  4. 创建实体类

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    @TableName("class")
    public class Clazz {
        //设置为主键且自增
        @TableId(type = IdType.AUTO)
        private Integer cid;
        private String cname;
        private String teacher;
    }
    
  5. 创建dao层接口

    @Repository
    public interface ClazzDao extends BaseMapper<Clazz> {
    }
    
  6. 创建service层和业务实现类

    • 接口

      public interface ClazzService {
          //添加
          public Clazz insert(Clazz clazz);
          //删除
          public int del(Integer id);
          //修改
          public Clazz updateById(Clazz clazz);
          //查询
          public Clazz getById(Integer id);
      }
      
    • 业务实现类

      @Service
      public class ClazzServiceImpl implements ClazzService {
          @Autowired
          private ClazzDao clazzDao;
          //查询
          @Override
          public Clazz getById(Integer id) {
              //查询数据库
              Clazz clazz = clazzDao.selectById(id);
              return clazz;
          }
          //增加
          @Override
          public Clazz insert(Clazz clazz) {
              clazzDao.insert(clazz);
              return clazz;
          }
          //删除
          @Override
          public int del(Integer id) {
              int i = clazzDao.deleteById(id);
              return i;
          }
      
          @Override
          public Clazz updateById(Clazz clazz) {
              //修改数据库
              int i = clazzDao.updateById(clazz);
              return clazz;
          }
      
  7. controller控制层

    @RestController
    @RequestMapping("/clazz")
    public class ClazzController {
        @Autowired
        private ClazzService clazzService;
    
        //添加
        @PostMapping("/insert")
        public Clazz insert(@RequestBody Clazz clazz){
            return clazzService.insert(clazz);
        }
    
        //根据id查询
        @GetMapping("/getById/{id}")
        public Clazz getById(@PathVariable Integer id){
            Clazz clazz = clazzService.getById(id);
            return clazz;
        }
        //删除
        @DeleteMapping("/del/{id}")
        public Integer del(@PathVariable Integer id){
            int del = clazzService.del(id);
            return del;
        }
        //编辑
        @PutMapping("/update")
        public Clazz update(@RequestBody Clazz clazz){
            return clazzService.updateById(clazz);
        }
    }
    
  8. 在main主函数中添加注入dao

    @SpringBootApplication
    @MapperScan("com.zmq.dao")
    public class SpringbootRedis02Application {
    
        public static void main(String[] args) {
            SpringApplication.run(SpringbootRedis02Application.class, args);
        }
    }
    

缓存处理在service层处理优化。【优化查、改、删方法】

  1. 在service业务处理类中注入Redis对象

    //在service层添加redis缓存
        @Autowired
        private RedisTemplate<String,Object> redisTemplate;
    
  2. 因为使用redisTemplate,需要序列化,所以,配置序列化配置工具类

    @Configuration
    public class RedisConfig {
        @Bean
        public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
            Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
            ObjectMapper om = new ObjectMapper();
            om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
            om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
            jackson2JsonRedisSerializer.setObjectMapper(om);
            RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
            template.setConnectionFactory(redisConnectionFactory);
            template.setKeySerializer(jackson2JsonRedisSerializer);
            template.setValueSerializer(jackson2JsonRedisSerializer);
            template.setHashKeySerializer(jackson2JsonRedisSerializer);
            template.setHashValueSerializer(jackson2JsonRedisSerializer);
            template.afterPropertiesSet();
            return template;
        }
    }
    

1.5.1 查询

  1. 获取redis操作字符串的对象
  2. 首先在Redis缓存中查询,如果有直接返回,不需要在访问数据库查询——get方法
  3. 如果Redis缓存中没有,再查询数据库,若在数据库中查询到,就将该数据添加到缓存中——set方法
//查询
    @Override
    public Clazz getById(Integer id) {
        //获取redis操作字符串的对象
        ValueOperations<String, Object> forValue = redisTemplate.opsForValue();
        //1.查询redis缓存是否命中
        Object o = forValue.get("clazz::" + id);
        //表示缓存命中
        if(o!=null){
            return (Clazz) o;
        }
        //查询数据库
        Clazz clazz = clazzDao.selectById(id);
        //如果数据库存在,将该值添加到缓存中
        if(clazz!=null){
            forValue.set("clazz::" + id,clazz);
        }
        return clazz;
    }

1.5.2 修改

若修改操作成功,返回值大于0,就将其数据同步到缓存中——set方法

 @Override
    public Clazz updateById(Clazz clazz) {
        //修改数据库
        int i = clazzDao.updateById(clazz);
        if(i>0){
            //修改缓存
            redisTemplate.opsForValue().set("clazz::"+clazz.getCid(),clazz);
        }
        return clazz;
    }

1.5.3 删除

若数据库删除操作成功,返回值大于0,就根据id删除缓存中该数据——delete方法

 @Override
    public int delete(Integer cid) {
        int i = clazzDao.deleteById(cid);
        if(i>0){
            //删除缓存
            redisTemplate.delete("clazz::"+cid);
        }
        return i;
    }

1.6 使用缓存注解完成缓存功能

发现:业务层代码除了要维护核心业务功能外,额外还要维护缓存的代码

如何解决:使用AOP面向切面编程——注解

步骤:

  1. 添加配置spring使用的缓存组件
  2. 开启注解驱动——@EnableCaching

配置文件

@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)) //缓存过期10分钟 ---- 业务需求。
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))//设置key的序列化方式
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer)) //设置value的序列化
                .disableCachingNullValues();
        RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
                .cacheDefaults(config)
                .build();
        return cacheManager;
    }

开启注解驱动

@SpringBootApplication
@MapperScan("com.zmq.dao")
@EnableCaching
public class SpringbootRedis02Application {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootRedis02Application.class, args);
    }
}

1.6.1 查询——@Cacheable

//查询
    @Cacheable(cacheNames ={ "clazz"}, key = "#id")
    @Override
    public Clazz getById(Integer id) {
        //查询数据库
        Clazz clazz = clazzDao.selectById(id);
        return clazz;
    }

Cacheable:表示查询时使用的注解

cacheNames:缓存的名称

key:缓存的唯一标识

在方法体之前执行

  1. 查询缓存中是否存在名称为cacheNames::key的值
  2. 如果存在则方法不会执行
  3. 如果不存在,则执行方法体并把方法的返回结果放入缓存中cacheNames::key

1.6.2 修改——@CachePut

 @CachePut(cacheNames = "clazz", key = "#clazz.cid")
    @Override
    public Clazz updateById(Clazz clazz) {
        //修改数据库
        int i = clazzDao.updateById(clazz);
        return clazz;
    }

CachePut:表示修改时使用的注解

  1. 先执行方法体
  2. 把方法的返回结果放入缓存中

1.6.3 删除——@CacheEvict

  @CacheEvict(cacheNames = "clazz", key = "#id")
    @Override
    public int delete(Integer cid) {
        int i = clazzDao.deleteById(cid);
        return i;
    }

CacheEvict:表示删除时使用的注解 Evict:驱逐

  1. 先执行方法体
  2. 把缓存中名称为cacheNames::key的值删除

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

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

相关文章

05 capture软件创建元器件库(以STM32为例)

05 创建元器件库_以STM32为例 一、新建原理图库文件二、新建器件三、开始创建元器件 一些IC类元件&#xff0c;需要自己创建元器件库。 先看视频&#xff0c;然后自己创建STM32F103C8T6的LQFP48的元器件。 STM32F103C8T6是目前为止&#xff0c;自己用的最多的芯片。 先要有数据…

nodejs安装及环境配置建材商城管理系统App

✌网站介绍&#xff1a;✌10年项目辅导经验、专注于计算机技术领域学生项目实战辅导。 ✌服务范围&#xff1a;Java(SpringBoo/SSM)、Python、PHP、Nodejs、爬虫、数据可视化、小程序、安卓app、大数据等设计与开发。 ✌服务内容&#xff1a;免费功能设计、免费提供开题答辩P…

文件包涵条件竞争(ctfshow82)

Web82 利用 session.upload_progress 包含文件漏洞 <!DOCTYPE html> <html> <body> <form action"https://09558c1b-9569-4abd-bf78-86c4a6cb6608.challenge.ctf.show//" method"POST" enctype"multipart/form-data"> …

C语言的发展过程介绍

引言 C语言&#xff0c;由丹尼斯里奇&#xff08;Dennis Ritchie&#xff09;在20世纪70年代初期于贝尔实验室开发&#xff0c;是计算机科学史上最具影响力的编程语言之一。本文将概述C语言的发展历程&#xff0c;并提供一些代码示例来展示其演变。 起源&#xff1a;UNIX和C语言…

自动化测试--WebDriver API

1. 元素定位方法 通过 ID 定位&#xff1a;如果元素具有唯一的 ID 属性&#xff0c;可以使用 findElement(By.id("elementId")) 方法来定位元素。通过 Name 定位&#xff1a;使用 findElement(By.name("elementName")) 来查找具有指定名称的元素。通过 Cl…

重生之“我打数据结构,真的假的?”--5.堆(无习题)

1.堆的概念与结构 如果有⼀个关键码的集合 &#xff0c;把它的所有元素按完全⼆叉树的顺序存储⽅ 式存储&#xff0c;在⼀个⼀维数组中&#xff0c;并满⾜&#xff1a; &#xff08; 且 &#xff09;&#xff0c; i 0、1、2... &#xff0c;则称为⼩堆(或⼤堆)。将根结点最⼤的…

逻辑处理模块:FPGA复旦微JFM7VX690T36+网络加速器:雄立XC13080-500C

逻辑处理模块通常是指在计算机系统、软件应用或电子设备中负责执行逻辑运算和决策过程的组件。 在不同的领域和技术中&#xff0c;逻辑处理模块可能有不同的实现方式和名称&#xff0c;但它们的核心功能都是基于输入数据进行逻辑判断和处理&#xff0c;并产生相应的输出结果。下…

GO-学习-03-基本数据类型

数据类型&#xff1a;基本数据类型和复合数据类型 基本数据类型&#xff1a;整型、浮点型、布尔型、字符串 复合数据类型&#xff1a;数组、切片、结构体、函数、map、通道&#xff08;channel&#xff09;、接口 整型&#xff1a; package main import "fmt" im…

react-native从入门到实战系列教程一环境安装篇

充分阅读官网的环境配置指南&#xff0c;严格按照他的指导作业&#xff0c;不然你一直只能在web或沙箱环境下玩玩 极快的网络和科学上网&#xff0c;必备其中的一个较好的心理忍受能力&#xff0c;因为上面一点就可以让你放弃坚持不懈&#xff0c;努力尝试 成功效果 三大件 …

「Unity3D」场景中的距离单位Unit与相关设置PixelsToUnits、PixelsPerUnit

GameObject在场景的位置Position&#xff0c;并没有明确是什么具体单位——如&#xff1a;Transform的x、y、z&#xff0c;或RectTransform的PosX、PosY、PosZ。而RectTransform在面板上显示的Width和Height&#xff0c;也没有具体单位&#xff0c;其实并不是像素。 事实上&am…

python+vue3+onlyoffice在线文档系统实战20240725笔记,首页开发

解决遗留问题 内容区域的高度没有生效&#xff0c;会随着菜单的高度自动变化。 解决方案&#xff1a;给侧边加上一个最小高度。 首页设计 另一种设计&#xff1a; 进来以后&#xff0c;是所有的文件夹和最近的文件。 有一张表格&#xff0c;类似于Windows目录详情&…

友盟U-APM——优秀的前端性能监控工具

在数字化转型浪潮的推动下,移动应用已成为企业连接用户、驱动业务增长的核心载体。然而,随着应用复杂度的日益提升,用户对于应用性能稳定性的期待也水涨船高。面对应用崩溃、卡顿、加载缓慢等频发问题,如何确保应用的流畅运行,成为产研团队亟待解决的关键挑战。在此背景下,友盟…

vite5-macos仿macOS网页osx管理系统|vue3+arcoDesign桌面os

基于vite5.xvue3arco-design原创自研网页版os管理框架ViteWebOS。 使用最新前端技术vite5vue3pinia2arcoDesignsortablejsecharts搭建网页pc版桌面os式后台管理系统解决方案。支持自定义桌面栅格布局引擎、可拖拽桌面图标、多屏分页管理、自定义桌面壁纸主题、毛玻璃虚化背景等…

【漏洞复现】E-Cology OA——WorkflowServiceXml——SQL注入

声明&#xff1a;本文档或演示材料仅供教育和教学目的使用&#xff0c;任何个人或组织使用本文档中的信息进行非法活动&#xff0c;均与本文档的作者或发布者无关。 文章目录 漏洞描述漏洞复现测试工具 漏洞描述 E-Cology OA协同商务系统是一款面向中大型组织的数字化办公产品…

LeNet卷积神经网络,手写数字识别

1. LeNet卷积神经网络的概念 先看看GPT的回答 有的资料中分层为 他们之间得差别就在于gpt的卷积层c5和上图中的全连接层1是同一种概念&#xff0c;因为该层使用的是5*5的卷积核&#xff0c;步长为一&#xff0c;根据公式可以算出输出的大小即是1X1的大小 训练参数是卷积核的大…

sentinel 服务流量控制 、熔断降级

1、什么是 sentinel,可以用来干什么 sentinel是用来在微服务系统中保护微服务对的作用,如何避免服务的雪崩、熔断、降级,说白了就是用来替换hystrix。 Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。 官网:GitHub - alibaba/Se…

Python从0到100(四十三):数据库与Django ORM 精讲

前言&#xff1a; 零基础学Python&#xff1a;Python从0到100最新最全教程。 想做这件事情很久了&#xff0c;这次我更新了自己所写过的所有博客&#xff0c;汇集成了Python从0到100&#xff0c;共一百节课&#xff0c;帮助大家一个月时间里从零基础到学习Python基础语法、Pyth…

08 capture软件新建原理图 09 原理图添加元器件 10 原理图信号连通 11 原理图电源和地连通

08 capture软件新建原理图 && 09 原理图添加元器件 && 10 原理图信号连通 && 11 原理图电源和地连通 第一部分 08 capture软件新建原理图第二部分 09 原理图添加元器件第三部分 10 原理图信号连通第四部分 11 原理图电源和地连通 第一部分 08 capture软…

服务器重启了之后就卡在某个页面了,花屏,如何解决??

&#x1f3c6;本文收录于《CSDN问答解惑-专业版》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收…

LC61----1374. 生成每种字符都是奇数个的字符串(字符串)---java版

1.题目 2.思路 &#xff08;1&#xff09;题目要生成每种字符是奇数个的字符串。 &#xff08;2&#xff09;所以直接用参数n%2来判断。 (3)返回的字符串必须只含小写英文字母。如果存在多个满足题目要求的字符串&#xff0c;则返回其中任意一个即可。 (4)感觉题目不是很规范哈…