SpringBoot 缓存

在这里插入图片描述

个人简介:Java领域新星创作者;阿里云技术博主、星级博主、专家博主;正在Java学习的路上摸爬滚打,记录学习的过程~
个人主页:.29.的博客
学习社区:进去逛一逛~

在这里插入图片描述

目录

  • 一、缓存的作用
  • 二、SpringBoot启用缓存
  • 三、SpringBoot可整合的缓存技术
  • 四、缓存使用案例——收集验证码
    • 实体类开发
    • 业务层开发
    • 工具类(生成验证码)
    • 控制层开发
    • SpringBoot启动类
    • 测试
  • 五、变更缓存供应商Ehcache


一、缓存的作用



缓存

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




二、SpringBoot启用缓存


SpringBoot提供了缓存技术,方便缓存的使用

  • 启用缓存
  • 设置进入缓存的数据
  • 设置读取缓存的数据

pom.xml导入缓存相关的起步依赖

        <!--缓存功能的起步依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>

SpringBoot启动类,添加@EnableCaching注解,启用缓存

@SpringBootApplication
@EnableCaching        //此注解表示开启缓存功能
public class Springboot4CacheApplication {

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

}


业务层组件,使用@Cacheable注解

value属性:存放缓存的位置,可随意定义

key属性:使用 # + 参数名 的方式设置缓存的数据

@Override
@Cacheable(value = "cacheSpace",key = "#id")
public Book getById(Integer id){
    return bookMapper.selectById(id);
}



三、SpringBoot可整合的缓存技术



  • SpringBoot提供的缓存技术除了提供默认的方案,还可以对其他缓存技术进行整合,统一接口,方便缓存技术的开发与管理。

常见的SpringBoot可整合的缓存技术

  • Generic
  • JCache
  • Ehcache
  • Hazelcast
  • Infinispan
  • Couchbase
  • Redis
  • Caffenine
  • Simple(默认)
  • memcached




四、缓存使用案例——收集验证码



需求

  • 输入手机号获取验证码,组织文档以短信形式发送给用户(页面模拟)
  • 输入手机号和验证码以验证结果

需求分析

  • 提供Controller组件,传入手机号,业务层通过手机号计算出独有的6位数验证码数据,存入缓存后返回此数据;
  • 提供Controller组件,传入手机号与验证码,业务层通过手机号从缓存中读取验证码,与输入的验证码进行比对,返回最终结果;

实体类开发


lombok快速开发实体类

        <!--导入lombok依赖-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

import lombok.Data;

/**
 * @author .29.
 * @create 2023-04-02 22:08
 * 使用@Data注解,提供Getter、Setter和toString()
 */
@Data
public class SMSCode {
    //电话号码
    private String phoneNumber;
    //验证码
    private String code;
}



业务层开发


业务层接口

/**
 * @author .29.
 * @create 2023-04-02 22:12
 */

public interface SMSCodeService {
    //模拟向sm卡发送验证码
    public String sendCodeToSMS(String phoneNumber);

    //验证验证码是否正确
    public boolean checkCode(SMSCode smsCode);
}


业务层接口实现类

  • 业务层组件中,使用了缓存功能,缓存功能的开启需要在SpringBoot工程的启动类中使用@EnableCaching开启缓存功能。
/**
 * @author .29.
 * @create 2023-04-02 22:15
 */
@Service
public class SMSCodeServiceImpl implements SMSCodeService {
    @Autowired
    private CodeUtils utils;  //自动装配工具类对象(工具类中提供了生成验证码的算法)

    @Override
    //@Cacheable注解不适用,缓存会被读取,导致前后两次验证码重复
    //@Cacheable(value="smsCode",key = "#phoneNumber")
    //@CachePut注解,缓存只可放不可读
    @CachePut(value="smsCode",key = "#phoneNumber")
    public String sendCodeToSMS(String phoneNumber) {
        return utils.generator(phoneNumber);
    }

    @Override
    public boolean checkCode(SMSCode smsCode) {
        //取出内存中的验证码与传递过来的参数比对,如果相同,返回true
        String code = smsCode.getCode();
        String cacheCode = utils.get(smsCode.getPhoneNumber());
        return cacheCode.equals(code);
    }
}



工具类(生成验证码)


工具类实现

/**
 * @author .29.
 * @create 2023-04-02 22:26
 */
@Component
public class CodeUtils {
    //为不足六位数的验证码补0用
    private String[] patch = {"000000","00000","0000","000","00","0",""};

    //加密,生成验证码
    public String generator(String phoneNumber){
        //获取手机号的hashCode值
        int hash = phoneNumber.hashCode();
        //设置一个加密码
        int encryption = 20230209;
        //获取第一次加密结果
        long result = hash ^ encryption;
        //第二次加密,第一次加密结果与当前时间进行异或操作
        long nowTime = System.currentTimeMillis();
        result = result ^ nowTime;
        //获取第二次加密结果的后六位
        long code = result % 1000000;
        code = code < 0 ? -code : code;//避免验证码为负值
        //转化为字符串
        String codeStr = code+"";
        int len = codeStr.length();
        return patch[len]+codeStr;
    }

    //设置phoneNumber的缓存,方法返回值为null,有缓存则返回缓存数据,没有才返回null
    @Cacheable(value="smsCode",key = "#phoneNumber")
    public String get(String phoneNumber){
        return null;
    }

}



控制层开发


/**
 * @author .29.
 * @create 2023-04-02 22:16
 */
//用于标记控制器类。@RestController 是 @Controller 和 @ResponseBody 的组合注解,用于标记 RESTful 风格的控制器类。
@RestController
@RequestMapping("/sms")
public class SMSCodeController {

    @Autowired
    private SMSCodeService service; //自动装配业务层组件

    //获取验证码
    @GetMapping
    public String getCode(String phoneNumber){
        String code = service.sendCodeToSMS(phoneNumber);
        return code;
    }

    //判断验证码是否正确
    @PostMapping
    public boolean checkCode(SMSCode smsCode){
        boolean result = service.checkCode(smsCode);
        return result;
    }
}



SpringBoot启动类


  • 注意要开启缓存功能
@SpringBootApplication
@EnableCaching        //此注解表示开启缓存功能
public class Springboot4CacheApplication {

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

}



测试


运行案例工程

在这里插入图片描述


使用国产postMAN测试功能

  • 使用页面模拟接收验证码:(每次发送请求,验证码都不会重复)

在这里插入图片描述


  • 模拟验证码比对校验:(只有当次手机号码与验证码匹配,才会返回true)

在这里插入图片描述



五、变更缓存供应商Ehcache



pom.xml导入Ehcache依赖

        <dependency>
            <groupId>net.sf.ehcache</groupId>
            <artifactId>ehcache</artifactId>
        </dependency>

application.yml配置文件

  • 设置使用ehcache的缓存
spring:
  cacahe:
    type: ehcache

配置Ehcache的xml配置文件

  • 其中的name属性值,需要保证与你注解中设置的缓存位置一致
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
         updateCheck="false">
    <diskStore path="D:\ehcache" />

    <!--默认缓存策略 -->
    <!-- external:是否永久存在,设置为true则不会被清除,此时与timeout冲突,通常设置为false-->
    <!-- diskPersistent:是否启用磁盘持久化-->
    <!-- maxElementsInMemory:最大缓存数量-->
    <!-- overflowToDisk:超过最大缓存数量是否持久化到磁盘-->
    <!-- timeToIdleSeconds:最大不活动间隔,设置过长缓存容易溢出,设置过短无效果,可用于记录时效性数据,例如验证码-->
    <!-- timeToLiveSeconds:最大存活时间-->
    <!-- memoryStoreEvictionPolicy:缓存清除策略-->
    <defaultCache
        eternal="false"
        diskPersistent="false"
        maxElementsInMemory="1000"
        overflowToDisk="false"
        timeToIdleSeconds="60"
        timeToLiveSeconds="60"
        memoryStoreEvictionPolicy="LRU" />

    <cache
        name="smsCode"  
        eternal="false"
        diskPersistent="false"
        maxElementsInMemory="1000"
        overflowToDisk="false"
        timeToIdleSeconds="10"
        timeToLiveSeconds="10"
        memoryStoreEvictionPolicy="LRU" />

</ehcache>

  • 完成上述配置,缓存技术也就更换完成了。

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

腾讯云邮件推送如何设置?群发邮件的技巧?

腾讯云邮件推送功能有哪些&#xff1f;怎么有效使用邮件推送&#xff1f; 腾讯云邮件推送以其稳定、高效的特点&#xff0c;受到了众多企业的青睐。那么&#xff0c;腾讯云邮件推送如何设置呢&#xff1f;又有哪些群发邮件的技巧呢&#xff1f;下面AokSend就来详细探讨一下。 …

Express进阶升级

Express进阶升级&#x1f199; 本篇文章&#xff0c;学习记录于&#xff1a;尚硅谷&#x1f3a2; 文章简单学习总结&#xff1a;如有错误 大佬 &#x1f449;点. 前置知识&#xff1a;需要掌握了解&#xff1a; JavaScript基础语法 、Node.JS环境API 、前端工程\模块化、Expr…

nvm基本使用

nvm基本使用 文章目录 nvm基本使用1.基本介绍2.下载地址3.常用指令 1.基本介绍 NVM是一个用于管理 Node.js 版本的工具。它允许您在同一台计算机上同时安装和管理多个 Node.js 版本&#xff0c;针对于不同的项目可能需要不同版本的 Node.js 运行环境。 NVM 主要功能&#xff…

【Redis | 第十篇】Redis与MySQL保证数据一致性(两种解决思路)

文章目录 10.Redis和MySQL如何保证数据一致性10.1双写一致性问题10.2数据高度一致性10.3数据同步允许延时10.3.1中间件通知10.3.2延迟双删 10.Redis和MySQL如何保证数据一致性 10.1双写一致性问题 Redis作为缓存&#xff0c;它是如何与MySQL的数据保持同步的呢&#xff1f;特…

PHP 错误 Unparenthesized `a ? b : c ? d : e` is not supported

最近在一个新的服务器上测试一些老代码的时候得到了类似上面的错误&#xff1a; [Thu Apr 25 07:37:34.139768 2024] [php:error] [pid 691410] [client 192.168.1.229:57183] PHP Fatal error: Unparenthesized a ? b : c ? d : e is not supported. Use either (a ? b : …

『FPGA通信接口』串行通信接口-SPI

文章目录 1.SPI简介2.控制时序3.Dual、Qual模式4.例程设计与代码解读5.SPI接口实战应用5.1时序要求5.2仿真时序图5.3代码设计 6.传送门 1.SPI简介 SPI是串行外设接口&#xff08;Serial Peripheral Interface&#xff09;的缩写&#xff0c;通常说SPI接口或SPI协议都是指SPI这…

将文件导入数据库

#include <stdio.h> #include <sqlite3.h> #include <string.h> int main(int argc, const char *argv[]) { //打开数据库 sqlite3 *db NULL; if(sqlite3_open("./dict.db",&db) ! SQLITE_OK){ printf("sqlite…

5G随身WiFi推荐测评:品速5G VS 格行5G随身WiFi,随身wifi哪个品牌网速好?性价比更高?

玩游戏卡顿遭吐槽&#xff0c;直播掉线成笑柄&#xff0c;4G网络已难满足需求。5G随身wifi虽受追捧&#xff0c;但价格较高令人犹豫。面对众多品牌&#xff0c;随身WiFi哪个品牌靠谱呢&#xff1f;性价比高呢&#xff1f;今天就来测评一下口碑最好的无线随身WiFi格行5G随身wifi…

新能源车载芯片分析

新能源汽车市场正迸发出巨大的活力&#xff0c;传统主机厂和新势力都纷纷推出各种车型&#xff0c;打起了价格战&#xff0c;各种新技术让人眼花缭乱。当前&#xff0c;战场硝烟弥漫&#xff0c;新能源汽车公司犹如春秋时期的各诸侯国。车载芯片作为新能源汽车的关键组成部分&a…

NDK 基础(一)—— C 语言知识汇总

1、数据类型 在 C 语言中&#xff0c;数据类型可以分为如下几类&#xff1a; 基本数据类型&#xff1a; 整数类型&#xff08;Integer Types&#xff09;&#xff1a;是算数类型&#xff0c;包括如下几种&#xff1a; int&#xff1a;用于表示整数数据&#xff0c;通常占用四个…

nvm 切换 Node 版本失败

创建vue3项目时&#xff0c;需要切换到更高版本的 node&#xff0c;于是使用 nvm (node 包版本管理工具)进行版本切换 切换版本时&#xff0c;显示成功&#xff0c;但再次查看当前 node 版本时&#xff0c;发现没切换过来。 解决方法&#xff1a; where node 查看node的安装…

车道分割YOLOV8-SEG

车道分割YOLOV8-SEG&#xff0c;训练得到PT模型&#xff0c;然后转换成ONNX&#xff0c;OPENCV的DNN调用&#xff0c;支持C,PYTHON,ANDROID开发 车道分割YOLOV8-SEG

深圳工厂车间降温通风设备

深圳工厂降温方案多种多样&#xff0c;可以根据工厂的具体情况和需求来选择合适的方案。以下是一些常见的降温方案&#xff1a; 通风换气&#xff1a;通过安装负压风机或冷风机等设备&#xff0c;加强通风换气&#xff0c;将室内热空气排出&#xff0c;吸入室外相对凉爽的空气…

零基础俄语培训哪家好,柯桥俄语培训

1、Мощный дух спасает расслабленное тело. 强大的精神可以拯救孱弱的肉体。 2、Единственное правило в жизни, по которому нужно жить — оставаться человеком в лю…

WSL及UBUNTU及xfce4安装

如何拥有Linux服务器&#xff1f; wsl 是适用于 Linux 的 Windows 子系统&#xff08;Windows Subsystem for Linux&#xff09;。是一个为在Windows 10和Windows Server 2019上能够原生运行Linux二进制可执行文件&#xff08;ELF格式&#xff09;的兼容层&#xff0c;可让开发…

Docker 的数据管理 端口映射 容器互联 镜像创建

一 Docker 的数据管理 1 管理 Docker 容器中数据主要有两种方式&#xff1a; 数据卷&#xff08;Data Volumes&#xff09; 数据卷容器&#xff08;DataVolumes Containers&#xff09;。 1.1 数据卷 数据卷是一个供容器使用的特殊目录&#xff0c;位于容器中。可将宿主机…

数据污染对大型语言模型的潜在影响

大型语言模型&#xff08;LLMs&#xff09;中存在的数据污染是一个重要问题&#xff0c;可能会影响它们在各种任务中的表现。这指的是LLMs的训练数据中包含了来自下游任务的测试数据。解决数据污染问题至关重要&#xff0c;因为它可能导致结果偏倚&#xff0c;并影响LLMs在其他…

linux 中 make 和 gmake的关系

1. 关系 gmake特指GNU make。 make是指系统默认的make实现; 在大多数Linux发行版中&#xff0c;make就是GNU make&#xff0c;但是在其他unix中&#xff0c;gmake可以指代make的某些其他实现&#xff0c;例如BSD make或各种商业unix的make实现。 gmake是GNU Make的缩写。 Linux…

【基础C-递归的易错思路】

目录 1. 分析2. 代码3. 结果&#xff1a; 1. 分析 现在要写一个小程序&#xff0c;实现输入整型&#xff1a;4268&#xff0c;输出字符:‘4’,‘2’,‘6’,‘8’,思路很简单&#xff0c;就是进行整数的除10&#xff0c;结果对10求模就行&#xff0c;但是得到的值是逆序排列&…

Vue 组件分类、局部注册和全局注册

文章目录 背景知识组件分类安装 vue-cli示例设置组件局部注册设置组件全局注册 背景知识 开发 Vue 的两种方式&#xff1a; 核心包传统开发模式&#xff1a;基于 html / css / js 文件&#xff0c;直接引入核心包&#xff0c;开发 Vue。工程化开发模式&#xff1a;基于构建工…