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 + "]"; } }
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); }
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); } }
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(); } }
基本注解
我们需要了解的一些基本注解有:
@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我们是如何整合的吧~