【黑马程序员SpringBoot2全套视频教程,springboot零基础到项目实战(spring boot2完整版)】
现在我们的应用,不管是APP还是网页,都是从数据库中取存数据使用
如果长期的对数据库进行访问,这样数据库的压力会越来越大【这样数据库就会成为整个系统的操作瓶颈】
其实这么大的访问量中,可能会有【或许说一定会有】相同的操作
能不能有一块儿空间,里面存下经常访问的数据,APP去访问它,它去访问数据库
【这样就可以有效降低数据库的压力】
这一块空间,我们把它称为缓存 cache
所以定义:
我们来快速的模拟一个缓存,体验感受一下
创建一个新的工程模块
依赖都不勾,自己加
直接创建
一个全新的 SpringBoot 项目
【导坐标】
org.springframework.boot spring-boot-starter-web
org.projectlombok lombok
com.baomidou mybatis-plus-boot-starter 3.5.2
com.alibaba druid-spring-boot-starter 1.2.11
mysql mysql-connector-java runtime
注意是web 起步
【配置】
server:port: 80spring:datasource:druid:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/ssm_db?serverTimezone=UTCusername: rootpassword: 200039mybatis-plus:global-config:db-config:table-prefix: tbl_id-type: autoconfiguration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
【实体类】
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;}
【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 {
}
【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 getAll();}
【实现类】
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 {@Autowiredprivate BookDao bookDao;@Overridepublic boolean save(Book book) {return bookDao.insert(book) > 0;}@Overridepublic Book getById(Integer id) {return bookDao.selectById(id);}@Overridepublic boolean update(Book book) {return bookDao.updateById(book) > 0;}@Overridepublic boolean delete(Integer id) {return bookDao.deleteById(id) > 0;}@Overridepublic List getAll() {return bookDao.selectList(null);}
}
【控制器】
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 {@Autowiredprivate BookService bookService;@GetMapping("{id}")public Book get(@PathVariable Integer id){return bookService.getById(id);}@PostMappingpublic boolean save(@RequestBody Book book){return bookService.save(book);}@PutMappingpublic boolean update(@RequestBody Book book){return bookService.update(book);}@DeleteMapping("{id}")public boolean delete(@RequestBody Book book){return bookService.save(book);}@GetMappingpublic List getAll(){return bookService.getAll();}}
OK,启动服务器,直接在postman 中测试一下
OK,能用
现在的问题是,每执行一次查询
它都会在数据库那边执行一个对应的操作
比如我在点一次send
这就又做了一次【这样就会给数据库带来很大的压力,因为就算是相同的数据,也要去查询很多次】
【这个问题可以解决吗?】
我们快速做一下
进入业务层
private HashMap cache = new HashMap(); //现在这个集合就是我们的缓存了@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);
}
重启服务器
先来一次查询
第一次,要调用数据层
再来一次
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); //电话号码和验证码比对验证}
实现类
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 cache = new HashMap();@Overridepublic String get(String tele) { //生成验证码//拿给的电话的后六位作为验证码String code = tele.substring(tele.length() - 6);//把生成的验证码放入缓存cache.put(tele, code);return code;}//验证的时候,就拿传过来的电话号码,去和缓存中的验证码进行比对@Overridepublic boolean check(String tele, String code) {String querycode = cache.get(tele);return code.equals(querycode);}
}
复制一个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 {@Autowiredprivate MsgService msgService;//发送验证码@GetMapping("{tele}")public String get(@PathVariable String tele){return msgService.get(tele);}//校验@PostMappingpublic boolean check(String tele , String code){return msgService.check(tele,code);}}
OK,直接启动服务器
在postman 中进行测试
后六位被返回来作为验证码
进行校验
OK,没毛病
这个栗子就是表明
这个缓存的东西并不是我数据库里面的东西
【所以说:缓存不仅可以用于提高永久性存储介质的数据读取效率,还可以提供临时的数据存储空间】