SpringBoot

【黑马程序员SpringBoot2全套视频教程,springboot零基础到项目实战(spring boot2完整版)】

SpringBoot 开发实用篇


文章目录

  • SpringBoot
  • SpringBoot 开发实用篇
  • 5 整合第三方技术
  • 5.1 缓存的作用
  • 5.1.1 缓存介绍
  • 5.1.2 小结


5 整合第三方技术

5.1 缓存的作用
5.1.1 缓存介绍

springboot接口缓存注解 springboot常用缓存技术_缓存

现在我们的应用,不管是APP还是网页,都是从数据库中取存数据使用

如果长期的对数据库进行访问,这样数据库的压力会越来越大【这样数据库就会成为整个系统的操作瓶颈】

其实这么大的访问量中,可能会有【或许说一定会有】相同的操作

能不能有一块儿空间,里面存下经常访问的数据,APP去访问它,它去访问数据库

【这样就可以有效降低数据库的压力】

这一块空间,我们把它称为缓存 cache

所以定义:

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

我们来快速的模拟一个缓存,体验感受一下

创建一个新的工程模块

springboot接口缓存注解 springboot常用缓存技术_springboot接口缓存注解_02

springboot接口缓存注解 springboot常用缓存技术_缓存_03

依赖都不勾,自己加

直接创建

springboot接口缓存注解 springboot常用缓存技术_缓存_04

一个全新的 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 起步

springboot接口缓存注解 springboot常用缓存技术_缓存_05

【配置】

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 中测试一下

springboot接口缓存注解 springboot常用缓存技术_缓存_06

springboot接口缓存注解 springboot常用缓存技术_spring_07

OK,能用

现在的问题是,每执行一次查询

springboot接口缓存注解 springboot常用缓存技术_java_08

它都会在数据库那边执行一个对应的操作

比如我在点一次send

springboot接口缓存注解 springboot常用缓存技术_缓存_09

这就又做了一次【这样就会给数据库带来很大的压力,因为就算是相同的数据,也要去查询很多次】

【这个问题可以解决吗?】

我们快速做一下

进入业务层

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);
}

springboot接口缓存注解 springboot常用缓存技术_缓存_10

重启服务器

springboot接口缓存注解 springboot常用缓存技术_java_11

先来一次查询

springboot接口缓存注解 springboot常用缓存技术_缓存_12

第一次,要调用数据层

再来一次

springboot接口缓存注解 springboot常用缓存技术_spring_13

OK,不管来多少次,都不会再去调用数据层访问数据库了,这个数据已经在内存的集合里面了

当然这个缓存一直在我们的内存里面,万一内存炸了,所以还要考虑清空缓存的问题

【这就是缓存的一个简单模拟】

甚至于我们可以把缓存拆成两个缓存

springboot接口缓存注解 springboot常用缓存技术_spring boot_14

这就是多级缓存的设计结构

而且缓存还可以存储一些其他的外部数据

springboot接口缓存注解 springboot常用缓存技术_spring boot_15

这些数据不用进数据库,但是我们有必要把它存起来【比如手机验证码就是一个临时数据】

我们也可以模拟一下

做一个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,直接启动服务器

springboot接口缓存注解 springboot常用缓存技术_spring_16

在postman 中进行测试

springboot接口缓存注解 springboot常用缓存技术_springboot接口缓存注解_17

后六位被返回来作为验证码

进行校验

springboot接口缓存注解 springboot常用缓存技术_spring boot_18

OK,没毛病

这个栗子就是表明

springboot接口缓存注解 springboot常用缓存技术_java_19

这个缓存的东西并不是我数据库里面的东西

【所以说:缓存不仅可以用于提高永久性存储介质的数据读取效率,还可以提供临时的数据存储空间】

5.1.2 小结
  1. 缓存作用
  2. 自定义缓存