• SpringBoot SpringBoot 开发实用篇 5 整合第三方技术 5.1 缓存的作用


    SpringBoot

    【黑马程序员SpringBoot2全套视频教程,springboot零基础到项目实战(spring boot2完整版)】

    SpringBoot 开发实用篇

    5 整合第三方技术

    5.1 缓存的作用
    5.1.1 缓存介绍

    在这里插入图片描述

    现在我们的应用,不管是APP还是网页,都是从数据库中取存数据使用

    如果长期的对数据库进行访问,这样数据库的压力会越来越大【这样数据库就会成为整个系统的操作瓶颈】

    其实这么大的访问量中,可能会有【或许说一定会有】相同的操作

    能不能有一块儿空间,里面存下经常访问的数据,APP去访问它,它去访问数据库

    【这样就可以有效降低数据库的压力】

    这一块空间,我们把它称为缓存 cache

    所以定义:

    • 缓存是一种介于数据永久存储介质【比如数据库】与数据应用【APP、网页】之间的数据临时存储介质
    • 使用缓存可以有效的减少低速数据读取过程的次数(例如磁盘IO),提高系统性能
    • 缓存不仅可以用于提高永久性存储介质的数据读取效率,还可以提供临时的数据存储空间

    我们来快速的模拟一个缓存,体验感受一下

    创建一个新的工程模块

    在这里插入图片描述

    在这里插入图片描述

    依赖都不勾,自己加

    直接创建

    在这里插入图片描述

    一个全新的 SpringBoot 项目

    【导坐标】

    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-webartifactId>
    dependency>
    
    <dependency>
        <groupId>org.projectlombokgroupId>
        <artifactId>lombokartifactId>
    dependency>
    
    <dependency>
        <groupId>com.baomidougroupId>
        <artifactId>mybatis-plus-boot-starterartifactId>
        <version>3.5.2version>
    dependency>
    
    <dependency>
        <groupId>com.alibabagroupId>
        <artifactId>druid-spring-boot-starterartifactId>
        <version>1.2.11version>
    dependency>
    
    <dependency>
        <groupId>mysqlgroupId>
        <artifactId>mysql-connector-javaartifactId>
        <scope>runtimescope>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    注意是web 起步

    在这里插入图片描述

    【配置】

    server:
      port: 80
    
    spring:
      datasource:
        druid:
          type: com.alibaba.druid.pool.DruidDataSource
          driver-class-name: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://localhost:3306/ssm_db?serverTimezone=UTC
          username: root
          password: 200039
    
    mybatis-plus:
      global-config:
        db-config:
          table-prefix: tbl_
          id-type: auto
    
      configuration:
        log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    【实体类】

    package com.dingjiaxiong.domain;
    
    import lombok.Data;
    
    /**
     * ClassName: Book
     * date: 2022/10/20 21:29
     *
     * @author DingJiaxiong
     */
    
    @Data
    public class Book {
        
        private Integer id;
        private String type;
        private String name;
        private String description;
        
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    【dao】

    package com.dingjiaxiong.dao;
    
    import com.baomidou.mybatisplus.core.mapper.BaseMapper;
    import com.dingjiaxiong.domain.Book;
    import org.apache.ibatis.annotations.Mapper;
    
    /**
     * ClassName: BookDao
     * date: 2022/10/20 21:29
     *
     * @author DingJiaxiong
     */
    
    @Mapper
    public interface BookDao extends BaseMapper<Book> {
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    【service】

    package com.dingjiaxiong.service;
    
    import com.dingjiaxiong.domain.Book;
    
    import java.util.List;
    
    /**
     * ClassName: BookService
     * date: 2022/10/20 21:31
     *
     * @author DingJiaxiong
     */
    
    public interface BookService {
        
        public boolean save(Book book);
        public Book getById(Integer id);
        public boolean update(Book book);
        public boolean delete(Integer id);
        public List<Book> getAll();
        
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    【实现类】

    package com.dingjiaxiong.service.impl;
    
    import com.dingjiaxiong.dao.BookDao;
    import com.dingjiaxiong.domain.Book;
    import com.dingjiaxiong.service.BookService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import java.util.List;
    
    /**
     * ClassName: BookServiceImpl
     * date: 2022/10/20 21:32
     *
     * @author DingJiaxiong
     */
    
    @Service
    public class BookServiceImpl implements BookService {
        
        @Autowired
        private BookDao bookDao;
        
        @Override
        public boolean save(Book book) {
            return bookDao.insert(book) > 0;
        }
    
        @Override
        public Book getById(Integer id) {
            return bookDao.selectById(id);
        }
    
        @Override
        public boolean update(Book book) {
            return bookDao.updateById(book) > 0;
        }
    
        @Override
        public boolean delete(Integer id) {
            return bookDao.deleteById(id) > 0;
        }
    
        @Override
        public List<Book> getAll() {
            return bookDao.selectList(null);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    【控制器】

    package com.dingjiaxiong.controller;
    
    import com.dingjiaxiong.domain.Book;
    import com.dingjiaxiong.service.BookService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.*;
    
    import java.util.List;
    
    /**
     * ClassName: BookController
     * date: 2022/10/20 21:35
     *
     * @author DingJiaxiong
     */
    
    @RestController
    @RequestMapping("/books")
    public class BookController {
    
        @Autowired
        private BookService bookService;
    
        @GetMapping("{id}")
        public Book get(@PathVariable Integer id){
            return bookService.getById(id);
        }
    
        @PostMapping
        public boolean save(@RequestBody Book book){
            return bookService.save(book);
        }
    
        @PutMapping
        public boolean update(@RequestBody Book book){
            return bookService.update(book);
        }
    
        @DeleteMapping("{id}")
        public boolean delete(@RequestBody Book book){
            return bookService.save(book);
        }
    
        @GetMapping
        public List<Book> getAll(){
            return bookService.getAll();
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    OK,启动服务器,直接在postman 中测试一下

    在这里插入图片描述

    在这里插入图片描述

    OK,能用

    现在的问题是,每执行一次查询

    在这里插入图片描述

    它都会在数据库那边执行一个对应的操作

    比如我在点一次send

    在这里插入图片描述

    这就又做了一次【这样就会给数据库带来很大的压力,因为就算是相同的数据,也要去查询很多次】

    【这个问题可以解决吗?】

    我们快速做一下

    进入业务层

    private HashMap<Integer, Book> cache = new HashMap<Integer, Book>(); //现在这个集合就是我们的缓存了
    
    @Override
    public Book getById(Integer id) {
        //如果当前缓存中没有本次要查询的数据,则调用数据层进行查询,
        //否则直接从缓存中获取数据返回
        Book book = cache.get(id);
        //如果是空,那就调数据层进行查询,并存入集合
        if (book == null) {
            Book queryBook = bookDao.selectById(id);
            //放入缓存集合
            cache.put(id,queryBook);
            return queryBook;
        }
        //如果不是空,那就直接从缓存中返回对应数据
        return cache.get(id);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    在这里插入图片描述

    重启服务器

    在这里插入图片描述

    先来一次查询

    在这里插入图片描述

    第一次,要调用数据层

    再来一次

    在这里插入图片描述

    OK,不管来多少次,都不会再去调用数据层访问数据库了,这个数据已经在内存的集合里面了

    当然这个缓存一直在我们的内存里面,万一内存炸了,所以还要考虑清空缓存的问题

    【这就是缓存的一个简单模拟】

    甚至于我们可以把缓存拆成两个缓存

    在这里插入图片描述

    这就是多级缓存的设计结构

    而且缓存还可以存储一些其他的外部数据

    在这里插入图片描述

    这些数据不用进数据库,但是我们有必要把它存起来【比如手机验证码就是一个临时数据】

    我们也可以模拟一下

    做一个service

    package com.dingjiaxiong.service;
    
    /**
     * ClassName: MsgService
     * date: 2022/10/20 21:54
     *
     * @author DingJiaxiong
     */
    
    public interface MsgService {
    
        public String get(String tele); //电话号码
        public boolean check(String tele, String code); //电话号码和验证码比对验证
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    实现类

    package com.dingjiaxiong.service.impl;
    
    import com.dingjiaxiong.service.MsgService;
    import org.springframework.stereotype.Service;
    
    import javax.lang.model.element.NestingKind;
    import java.util.HashMap;
    
    /**
     * ClassName: MsgServiceImpl
     * date: 2022/10/20 21:55
     *
     * @author DingJiaxiong
     */
    
    @Service
    public class MsgServiceImpl implements MsgService {
    
        //定义一个缓存
        private HashMap<String , String> cache = new HashMap<String ,String>();
    
        @Override
        public String get(String tele) {  //生成验证码
            //拿给的电话的后六位作为验证码
            String code = tele.substring(tele.length() - 6);
            //把生成的验证码放入缓存
            cache.put(tele, code);
            return code;
        }
    
        //验证的时候,就拿传过来的电话号码,去和缓存中的验证码进行比对
        @Override
        public boolean check(String tele, String code) {
    
            String querycode = cache.get(tele);
            return code.equals(querycode);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    复制一个controller【改一下】

    package com.dingjiaxiong.controller;
    
    import com.dingjiaxiong.domain.Book;
    import com.dingjiaxiong.service.BookService;
    import com.dingjiaxiong.service.MsgService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.*;
    
    import java.util.List;
    
    /**
     * ClassName: BookController
     * date: 2022/10/20 21:35
     *
     * @author DingJiaxiong
     */
    
    @RestController
    @RequestMapping("/msg")
    public class MsgController {
    
        @Autowired
        private MsgService msgService;
    
        //发送验证码
        @GetMapping("{tele}")
        public String get(@PathVariable String tele){
            return msgService.get(tele);
        }
    
        //校验
        @PostMapping
        public boolean check(String tele , String code){
            return msgService.check(tele,code);
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    OK,直接启动服务器

    在这里插入图片描述

    在postman 中进行测试

    在这里插入图片描述

    后六位被返回来作为验证码

    进行校验

    在这里插入图片描述

    OK,没毛病

    这个栗子就是表明

    在这里插入图片描述

    这个缓存的东西并不是我数据库里面的东西

    【所以说:缓存不仅可以用于提高永久性存储介质的数据读取效率,还可以提供临时的数据存储空间】

    5.1.2 小结
    1. 缓存作用
    2. 自定义缓存
  • 相关阅读:
    EnvoyFilter实践: 通过解析子域名注入环境标识
    (六)admin-boot项目之全局处理预防xss攻击
    COMP3511 Spring 2022
    Debezium的基本使用(以MySQL为例)
    springboot基础篇(快速入门 + 完整项目案例)
    php rsa加解密
    小型气象站的分类和选型要点
    【LeetCode刷题笔记】DFS&BFS(一)
    截图快捷键ctrl加什么
    基于离散Markov模型的Web用户行为预测算法的研究
  • 原文地址:https://blog.csdn.net/weixin_44226181/article/details/127945429