SpringBoot
【黑马程序员SpringBoot2全套视频教程,springboot零基础到项目实战(spring boot2完整版)】
SpringBoot 开发实用篇
文章目录
- SpringBoot
- SpringBoot 开发实用篇
- 5 整合第三方技术
- 5.1 缓存的作用
- 5.1.1 缓存介绍
- 5.1.2 小结
5 整合第三方技术
5.1 缓存的作用
5.1.1 缓存介绍
现在我们的应用,不管是APP还是网页,都是从数据库中取存数据使用
如果长期的对数据库进行访问,这样数据库的压力会越来越大【这样数据库就会成为整个系统的操作瓶颈】
其实这么大的访问量中,可能会有【或许说一定会有】相同的操作
能不能有一块儿空间,里面存下经常访问的数据,APP去访问它,它去访问数据库
【这样就可以有效降低数据库的压力】
这一块空间,我们把它称为缓存 cache
所以定义:
- 缓存是一种介于数据永久存储介质【比如数据库】与数据应用【APP、网页】之间的数据临时存储介质
- 使用缓存可以有效的减少低速数据读取过程的次数(例如磁盘IO),提高系统性能
- 缓存不仅可以用于提高永久性存储介质的数据读取效率,还可以提供临时的数据存储空间
我们来快速的模拟一个缓存,体验感受一下
创建一个新的工程模块
依赖都不勾,自己加
直接创建
一个全新的 SpringBoot 项目
【导坐标】
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.11</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
注意是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
【实体类】
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<Book> {
}
【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();
}
【实现类】
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);
}
}
【控制器】
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();
}
}
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);
}
重启服务器
先来一次查询
第一次,要调用数据层
再来一次
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<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);
}
}
复制一个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);
}
}
OK,直接启动服务器
在postman 中进行测试
后六位被返回来作为验证码
进行校验
OK,没毛病
这个栗子就是表明
这个缓存的东西并不是我数据库里面的东西
【所以说:缓存不仅可以用于提高永久性存储介质的数据读取效率,还可以提供临时的数据存储空间】
5.1.2 小结
- 缓存作用
- 自定义缓存