一、缓存的作用
因此就有了缓存的作用:
代码模拟上面缓存的作用如下所示:
就拿以前我们做的通过id查询单条数据功能:
当开启服务器后,客户端访问该通过id查询单条数据功能时(假设连续访问两次):
那么问题来了,客户端要是一直访问该功能百次呢,难不成我们后台也要访问百次数据库?那客户端要是一直访问该功能我们后台就一直访问该功能的数据库,那岂不是上万次相同的操作的话,数据库不就废了
因此我们就可以设置一个缓存,当客户端请求该功能资源超过两次或者更多的时候,我们后台就不再通过访问数据库然后响应给客户端请求的资源了,而是通过该缓存把客户端请求的数据响应给客户(缓存中之所以会有客户端请求的数据资源:因为第一次客户端请求该资源的时候,我们就可以把该客户端的请求资源也存放到缓存当中,当客户端第二次甚至成千上万次再请求该资源的时候,我们后台就不用再调用数据库了,缓存就能直接把数据响应给客户端了,解决了数据库的压力问题)
缓存设置代码如下所示:
/**
* 定义一个缓存: 用HashMap集合即可 (也就是说把客户端访问过的相同的请求资源存放到HashMap集合的value中)
*
* HashMap<Integer,Book> : Integer----> key Book----> value
* 注:value设置成Book类型的原因是:等会可以把通过id查询出来的数据库中的数据存放到该Book类型的value中
* (因为从数据库中查出来的数据就是Book类型)
*/
private HashMap<Integer,Book> cache = new HashMap<Integer,Book>();
/**
* 5、通过id查询单条数据功能
*/
@GetMapping(value = "/{id}")
public Book selectById(@PathVariable Integer id){
/**
* 判断客户端请求资源的参数id,在缓存:HashMap集合中是否存放了该参数id的资源数据
*
*/
Book book = cache.get(id); // HashMap集合中:通过该id获取value数据
// 如果该value不为null,就说明该缓存中(HashMap集合中)已经存放了该请求参数id对应数据库中的数据资源
// 如果value为null,说明缓存中还没有存放过客户端请求参数id对应的数据,也就是说客户端第一次请求该资源数据
// 那么我们就直接让客户端访问数据库就行了,等第二次再请求该id资源的时候,就直接在缓存中响应给客户端数据即可,不再通过数据库
if (book == null){
// 如果该客户端请求参数id对应的缓存中的value没有数据,就说明客户端是第一次使用该id请求数据,那么直接访问数据库即可
// 调用业务层的通过id查询单条数据功能 (最终调用的是数据库)
Book book1 = bookService.selectById(id);
cache.put(id,book1); // 把从数据库中查询出来的数据和该此客户端请求的id参数 存放到缓存(HashMap集合中)中去,等第二次客户端再用该请求参数id请求
// 数据的时候,直接就判断不为null了,直接从缓存(HashMap集合)中把客户端请求访问的该id参数对应的数据响应给客户端即可
// 不再访问数据库了
return book1;
}
return cache.get(id); // 当多次访问该资源功能的时候,缓存中已经存放该资源数据了,直接就把缓存中的数据响应给客户端即可了,不用再麻烦数据库了
}
当设置好缓存后,客户端再访问通过id查询功能:(连续访问两次):
补充知识:通过上面的演示我们知道缓存中的数据是通过数据库提供过来的,是先把数据库中的数据存放到缓存当中,然后当客户端再次请求该资源的时候,直接把缓存中的数据响应给客户端即可
但是还有一种就是缓存中的数据并不是通过数据库提供的,而是从外界把数据存放到缓存当中的。
就比如我们很久没有登录过的一个网站,现在我们登录了让我们输入手机号和一个验证码,我们想这个验证码他肯定不会是存放在数据库当中的,而是临时生成的一个验证码
代码演示如下所示:
package com.Bivin.service.impl;
import com.Bivin.service.MsgService;
import org.springframework.stereotype.Service;
import java.util.HashMap;
@Service
public class MsgServiceImpl implements MsgService {
/**
* 定义一个缓存:还是用HashMap集合即可
* HashMap<String,String> : String----> key String----> value
*/
private HashMap<String,String> cache=new HashMap<String,String>();
/**
* String tele: 该参数tele就是获取用户的手机号
*
* 该get方法:就是通过获取客户端填写的手机号,为该手机号生成一个验证码
*/
@Override
public String get(String tele) {
/**
* 我们这里就假定手机号的后六位是验证码
*/
String code = tele.substring(tele.length() - 6); // 假设这个手机号的后6位就是我们想要给客户端的验证码
cache.put(tele,code); // 我们直接把手机号和验证码放入到缓存当中,
// 当客户端输入手机号和验证码校验的时候,直接通过该客户端的手机号获取对应的value:验证码
// 判断一下是否和放入到缓存当中的验证码一致,一致的话就校验成功,不一致就校验失败
return code; // 把验证码响应给客户端,客户端就能拿着这个验证码,然后就能进行校验了
}
/**
* check(String tele, String code):
*
* String tele: 客户端输入的手机号 String code:客户端输入的验证码
*
* 该check方法: 校验功能
* 就是上面get方法,客户端通过输入手机号为该手机号获取到验证码后,就能到这里进行校验了,
* 因为上面该手机号生成的验证码我们也放入到了缓存当中了,因此这里只需要比对该用户输入的
* 手机号对应的验证码是否和我们存放到缓存中的手机号对应的验证码一致,
* 一致的话:就验证成功 不一致的话:就验证失败
*/
@Override
public boolean check(String tele, String code) {
String s = cache.get(tele); // 通过客户端输入的手机号,获取到存放在缓存中该手机号对应的验证码
return s.equals(code); // 判断客户端输入的验证码是否和缓存中的该手机号对应的验证码一致
}
}
总体代码逻辑:通过上面的代码客户端就可以先访问get方法,通过输入手机号拿到验证码,然后再访问check方法输入手机号和拿到的验证码进行与缓存中的该手机号对应的验证码进行校验。
因此我们也知道了,该缓存中的数据并不是数据库中提供的,而是我们运行的代码中提供的。