SpringBoot日记——缓存的使用

  SpringBoot核心技术的东西基本上都有介绍过了,接下来,进阶点~来说说缓存吧~

  缓存这个词不少同学应该不会很陌生。而我们这里主要使用的就是Redis。

  客户端第一次请求的时候是从库里拿出我们需要的数据,但如果每次查询都从库里拿,就会很耗时耗能。那么使用缓存以后,我们只需要第一次从库里拿完存到缓存中,只要不清除缓存,我们以后的请求都直接在缓存中拿数据,就会快很多很多。

  先给出几个基础的方法,包括Mapper/Bean/Controller,不然后边说的东西估计有些人会很懵。

package com.oooodin.cache.bean;

public class Employee {
    
    private Integer id;
    private String lastName;
    private String email;
    private Integer gender; //性别 1男  0女
    private Integer dId;
    
    
    public Employee() {
        super();
    }

    
    public Employee(Integer id, String lastName, String email, Integer gender, Integer dId) {
        super();
        this.id = id;
        this.lastName = lastName;
        this.email = email;
        this.gender = gender;
        this.dId = dId;
    }
    
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getLastName() {
        return lastName;
    }
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    public Integer getGender() {
        return gender;
    }
    public void setGender(Integer gender) {
        this.gender = gender;
    }
    public Integer getdId() {
        return dId;
    }
    public void setdId(Integer dId) {
        this.dId = dId;
    }
    @Override
    public String toString() {
        return "Employee [id=" + id + ", lastName=" + lastName + ", email=" + email + ", gender=" + gender + ", dId="
                + dId + "]";
    }

}
bean.Employee
import com.oooodin.cache.bean.Employee;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

public interface EmployeeMapper {

    // 查询
    @Select("SELECT * FROM employee WHERE id = #{id}")
    public Employee getEmpById(Integer id);

    // 更新
    @Update("UPDATE employee SET lastName = #{lastName},email = #{email},gender = #{gender},d_id=#{dId} WHERE id = #{id}")
    public void updateEmp(Employee employee);

    // 删除
    @Delete("DELETE FROM employee WHERE id = #{id}")
    public void deleteEmpById(Integer id);

    // 新增
    @Insert("INSERT INTO employee(lastName,email,genderm,d_id) VALUES(#{lastName},#{email},#{gender},#{dId})")
    public void insertEmp(Employee employee);
}
mapper.EmployeeMapper
import com.oooodin.cache.bean.Employee;
import com.oooodin.cache.mapper.EmployeeMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

@Service
public class EmployeeService {

    @Autowired
    EmployeeMapper employeeMapper;

    /**
     * 将方法结果进行缓存
     * 再要相同数据,直接从缓存中获取,不再调用方法
     *
     * @param id
     * @return
     */
    @Cacheable(cacheNames = "emp")
    public Employee getEmp(Integer id) {
        System.out.println("查询" + id + "号员工");
        Employee emp = employeeMapper.getEmpById(id);
        return emp;
    }

    @CachePut(cacheNames = "emp", key = "#result.id")
    public Employee updateEmp(Employee employee) {
        System.out.println("updateEmp:" + employee);
        employeeMapper.updateEmp(employee);
        return employee;
    }

    @CacheEvict(cacheNames = "emp", key = "#id")
    public void deleteEmp(Integer id) {
        employeeMapper.deleteEmpById(id);
    }
}
service.EmployeeService
import com.oooodin.cache.bean.Employee;
import com.oooodin.cache.service.EmployeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class EmployeeController {

    @Autowired
    EmployeeService employeeService;

    @GetMapping("/emp/{id}")
    public Employee getEmploee(@PathVariable("id") Integer id) {
        Employee emp = employeeService.getEmp(id);
        return emp;
    }

    @GetMapping("/emp")
    public Employee updateEmp(Employee employee) {
        Employee emp = employeeService.updateEmp(employee);
        return emp;
    }

    @GetMapping("/delete")
    public String deleteEmp(Integer id) {
        employeeService.deleteEmp(id);
        System.out.println("success");
        return "success to delete EMP with id =" + id.toString();
    }
}
controller.EmployeeController

 

基本注解

  我们需要了解的一些基本注解有:

    @EnableCache:开启基于注解的缓存。通常我们放在application的主方法中

    @Cacheable:针对方法请求参数对结果进行缓存
    @CachePut:保证方法的调用/执行,以及更新缓存
    @CacheEvict:清除缓存

  难么如何来使用呢?首先,在pom.xml中添加如下:

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

  这样,我们就关联了cache缓存。

  然后,我们创建数据,在数据库里录入些东西,让我们之后可以读取和展示数据。那么关于增删改查的,关于mapper/bean等方法我就不在这里写了,想了解的可以翻看前边的文章~

  下边是主程序的代码,我加了一些注释,告诉大家一些基本步骤

/**
 * 一、搭建环境
 * 1.导入数据库文件,创建出两个表
 * 2.创建javaBean封装数据库
 * 3.整合Mybatis数据源信息
 *      1.配置数据库
 *      2.使用注解版的MyBatis
 *          1)、使用@Mapper扫描包
 *          2)、创建Service和Controller
 * 二、缓存
 *      步骤:
 *          1、开启基于注解的缓存
 *          2、标注缓存注解即可
 *              @Cacheable
 *              @CacheEvict
 *              @CachePut
 */
@MapperScan("com.oooodin.cache.mapper")
@SpringBootApplication
@EnableCaching
public class CacheApplication {

    public static void main(String[] args) {
        SpringApplication.run(CacheApplication.class, args);
    }
}

  

  看到了吧,上边有个橙色的注解,那个就是开启了缓存的注解功能,这样我们方法中写的缓存注解就可以被识别和使用了。例如:

  这个方法的结果就会被写入到缓存中,我们可以启动主程序,然后在浏览器中多访问几次,看看打印了几次,如果只有1次,说明后边的请求都是从缓存中获得,而没有运行方法去查数据库,那么就成功了。

  http://localhost:8080/emp/1   <====用这个来查询1号员工,并存入缓存

    @Cacheable(cacheNames = "emp")
    public Employee getEmp(Integer id) {
        System.out.println("查询" + id + "号员工");
        Employee emp = employeeMapper.getEmpById(id);
        return emp;
    }

  继续来看:

  这个就是将缓存数据更新的作用,同时方法也一定会运行。也就是像之前那样多次请求的话,每次都会访问数据库了。那么我们为什么要用这个?

  这么说吧,当我们更新数据库的同时,同样更新缓存。然后我们再次请求一次。所以我们更新以后,再用上边的地址查询一下看看是不是有更新。

  http://localhost:8080/emp?id=1&lastName=张三&gender=2  <===这个是用来更新数据到数据库的,同时也可以更新缓存。

    @CachePut(cacheNames = "emp")
    public Employee updateEmp(Employee employee) {
        System.out.println("updateEmp:" + employee);
        employeeMapper.updateEmp(employee);
        return employee;
    }

  诶?是不是发现更新没问题,但是查询发现没变啊????

  来看这个参数:key。因为我们在查询的那个方法中如果没有设定key,就会默认以参数当做key值在保存。然后我们在更新的时候要对应key才行。所以(取结果的id):

  这回我们再刷新和查询的时候就会有变化了吧~

    @CachePut(cacheNames = "emp", key = "#employee.id")
    public Employee updateEmp(Employee employee) {
        System.out.println("updateEmp:" + employee);
        employeeMapper.updateEmp(employee);
        return employee;
    }

  

  在开发过程中,我们不光是要更新,也要清除缓存,不然一直存着也会有问题的~:

  这样,我们清除缓存名未emp中key是id的那条~,再次查询的时候,你会发现,我们又需要查询数据库重新保存缓存了。

  http://localhost:8080/delete?id=1  <===删除id是1的那条缓存

    @CacheEvict(cacheNames = "emp", key = "#id")
    public void deleteEmp(Integer id) {
        employeeMapper.deleteEmpById(id);
    }

  

  当然注解和参数,还有其他很多,我们可以去进入的jar包看一下具体的都有哪些,然后自己挨个尝试一下。比如Caching。这里我就不详细来说了(其实也没说多少东西……)

  对了,这里给大家推荐一下可以学习的地方。可以搜一下 尚硅谷讲的SpringBoot的搞基片(高级篇),里边讲的真的很不错,很详细。

  真正的教程不是视频或者书籍,而是官方API文档和源码。看懂这两个就能基本解决所有问题了,加油!

 

  下一篇文章,说一下redis我们是如何整合的吧~

posted @ 2018-08-14 15:48  碎冰  阅读(12773)  评论(0编辑  收藏  举报