《SpringBoot篇》17.SpringBoot内置缓存

简介: 《SpringBoot篇》17.SpringBoot内置缓存

一、缓存简介


说明:企业级应用主要作用是信息处理,当需要读取数据时,如果直接在数据库中读取,会对数据层非常大的压力,同时受限于数据库的访问效率,导致整体系统性能偏低。


image.png


解决方法:通常会在应用程序与数据库之间建立一种临时的数据存储机制,该区域中的数据在内存中保存,读写速度较快,可以有效解决数据库访问效率低下的问题。这一块临时存储数据的区域就是缓存。

image.png


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


二、 SpringBoot内置缓存


springboot技术提供有内置的缓存解决方案,可以帮助开发者快速开启缓存技术,并使用缓存技术进行数据的快速操作,例如读取缓存数据和写入数据到缓存。


1.导入springboot提供的缓存技术对应的starter

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

image.png


2.启用缓存

注:在引导类上方标注注解@EnableCaching配置springboot程序中可以使用缓存(这里使用的是MongoDB的项目)


package com.test;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
@SpringBootApplication
@EnableCaching
public class SpringbootMongodbApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringbootMongodbApplication.class, args);
    }
}


image.png


3.设置操作的数据是否使用缓存

注:使用@Cacheable注解,之后会有@Cacheable注解参数详解。


@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserDao userDao;
    @Cacheable(value="cacheSpace",key="#id")
    public User getById(Integer id) {
        return userDao.selectById(id);
    }
}

注:在业务方法上面使用注解@Cacheable声明当前方法的返回值放入缓存中, 其中必须要指定缓存的存储位置,以及缓存中保存当前方法返回值对应的名称。上例中value属性描述缓存的存储位置,可以理解为是一个存储空间名,key属性描述了缓存中保存数据的名称,使用#id读取形参中的id值作为缓存名称。


使用@Cacheable注解后,执行当前操作,如果发现对应名称在缓存中没有数据,就正常读取数据,然后放入缓存;如果对应名称在缓存中有数据,就终止当前业务方法执行,直接返回缓存中的数据。


4.补充有关缓存的注解

image.png

5.补充@Cacheable注解参数详解。

image.png

三、手机验证码案例


注:这是黑马的案例,有时间可以看一下,之前对我收货很大。

为了便于下面演示各种各样的缓存技术,我们创建一个手机验证码的案例环境,模拟使用缓存保存手机验证码的过程。


手机验证码案例需求如下:


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

输入手机号和验证码验证结果

为了描述上述操作,我们制作两个表现层接口,一个用来模拟发送短信的过程,其实就是根据用户提供的手机号生成一个验证码,然后放入缓存,另一个用来模拟验证码校验的过程,其实就是使用传入的手机号和验证码进行匹配,并返回最终匹配结果。下面直接制作本案例的模拟代码,先以上例中springboot提供的内置缓存技术来完成当前案例的制作。


步骤①:导入springboot提供的缓存技术对应的starter


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

步骤②:启用缓存,在引导类上方标注注解@EnableCaching配置springboot程序中可以使用缓存


@SpringBootApplication
//开启缓存功能
@EnableCaching
public class Springboot19CacheApplication {
    public static void main(String[] args) {
        SpringApplication.run(Springboot19CacheApplication.class, args);
    }
}

步骤③:定义验证码对应的实体类,封装手机号与验证码两个属性


@Data
public class SMSCode {
    private String tele;
    private String code;
}

步骤④:定义验证码功能的业务层接口与实现类

public interface SMSCodeService {
    public String sendCodeToSMS(String tele);
    public boolean checkCode(SMSCode smsCode);
}
@Service
public class SMSCodeServiceImpl implements SMSCodeService {
    @Autowired
    private CodeUtils codeUtils;
    @CachePut(value = "smsCode", key = "#tele")
    public String sendCodeToSMS(String tele) {
        String code = codeUtils.generator(tele);
        return code;
    }
    public boolean checkCode(SMSCode smsCode) {
        //取出内存中的验证码与传递过来的验证码比对,如果相同,返回true
        String code = smsCode.getCode();
        String cacheCode = codeUtils.get(smsCode.getTele());
        return code.equals(cacheCode);
    }
}

获取验证码后,当验证码失效时必须重新获取验证码,因此在获取验证码的功能上不能使用@Cacheable注解,@Cacheable注解是缓存中没有值则放入值,缓存中有值则取值。此处的功能仅仅是生成验证码并放入缓存,并不具有从缓存中取值的功能,因此不能使用@Cacheable注解,应该使用仅具有向缓存中保存数据的功能,使用@CachePut注解即可。


对于校验验证码的功能建议放入工具类中进行。


步骤⑤:定义验证码的生成策略与根据手机号读取验证码的功能


@Component
public class CodeUtils {
    private String [] patch = {"000000","00000","0000","000","00","0",""};
    public String generator(String tele){
        int hash = tele.hashCode();
        int encryption = 20206666;
        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;
    }
    @Cacheable(value = "smsCode",key="#tele")
    public String get(String tele){
        return null;
    }
}

步骤⑥:定义验证码功能的web层接口,一个方法用于提供手机号获取验证码,一个方法用于提供手机号和验证码进行校验


@RestController
@RequestMapping("/sms")
public class SMSCodeController {
    @Autowired
    private SMSCodeService smsCodeService;
    @GetMapping
    public String getCode(String tele){
        String code = smsCodeService.sendCodeToSMS(tele);
        return code;
    }
    @PostMapping
    public boolean checkCode(SMSCode smsCode){
        return smsCodeService.checkCode(smsCode);
    }
}
相关文章
|
8天前
|
缓存 NoSQL Java
SpringBoot实现缓存预热的几种常用方案
SpringBoot实现缓存预热的几种常用方案
|
8天前
|
缓存 NoSQL Java
Springboot 多级缓存设计与实现
Springboot 多级缓存设计与实现
|
8天前
|
缓存 NoSQL Java
spring cache整合redis实现springboot项目中的缓存功能
spring cache整合redis实现springboot项目中的缓存功能
51 1
|
6月前
|
缓存 NoSQL Java
分布式系列教程(03) -分布式Redis缓存(SpringBoot整合Redis)
分布式系列教程(03) -分布式Redis缓存(SpringBoot整合Redis)
109 0
|
6月前
|
缓存 Java Maven
微服务技术系列教程(07) - SpringBoot - 缓存的使用
微服务技术系列教程(07) - SpringBoot - 缓存的使用
49 0
|
8天前
|
缓存 NoSQL Java
【九】springboot整合redis实现启动服务时热点数据保存在全局和缓存
【九】springboot整合redis实现启动服务时热点数据保存在全局和缓存
59 0
|
7月前
|
缓存 数据可视化 NoSQL
【异常】springboot集成@Cacheable缓存乱码的问题解决方案
【异常】springboot集成@Cacheable缓存乱码的问题解决方案
172 1
|
8天前
|
缓存 NoSQL Java
面试官:SpringBoot如何实现缓存预热?
面试官:SpringBoot如何实现缓存预热?
89 0
|
8天前
|
缓存 NoSQL Java
springboot集成图片验证+redis缓存一步到位2
springboot集成图片验证+redis缓存一步到位2
|
8天前
|
缓存 NoSQL Java
springboot集成图片验证+redis缓存一步到位
springboot集成图片验证+redis缓存一步到位