springboot缓存cache
配置数据库环境
spring:
datasource:
username: root
password: abcde
url: jdbc:mysql://localhost:3306/springbootdata?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
driver-class-name: com.mysql.cj.jdbc.Driver
配置实体类和相对应的mapper文件
Employee实体类: 实体类要继承序列化,不然会失败
EmployeeMapper :
package com.codel.cache.pojo;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import org.springframework.stereotype.Repository;
//注入bean容器里面
@Repository
//使用mybatis操作数据库
@Mapper
public interface EmployeeMapper {
@Select("Select * from employee where id =#{id}")
Employee getEmpById(int id);
@Update("Update employee set lastName=#{lastName},email=#{email},gender=#{gender} where id=#{id}")
void updateEmp(Employee employee);
@Delete("Delete from employee where id=#{id}")
void deleteEmpById(int id);
}
配置service类和controller类
EmployeeService 类:
package com.codel.cache.service;
import com.codel.cache.pojo.Employee;
import com.codel.cache.pojo.EmployeeMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
@CacheConfig(cacheNames = "emp") //配置公共缓存的配置信息
@Service
public class EmployeeService {
@Autowired
EmployeeMapper employeeMapper;
/*
Cachemannager管理多个Cache组件,对缓存真正的CRUD操作在Cache组件中,每一个缓存组件有自己唯一的一个名字。
@Cacheable作用:将方法的运行结果进行缓存,以后再要相同的数据,从缓存中取
属性:
cacheNames/value: 指定缓存的名字;将方法的返回结果放在那个缓存中,数组的方式,可以指定多个缓存。
key: 缓存数据使用的key,默认使用方法参数的值; 可以使用SpEL表达式,#id表示参数的值,等同于 #a0 #p0 #root.args[0]
keyGenerator: key的生成器;也可以自己指定key的生成器的组件id key/keyGenerator 二选一使用
cacheManager: 指定缓存管理器;或者cacheResolver指定获取解析器 二选一使用
condition:指定符合条件的情况下才缓存: condition="#a0>1" 第一个参数大于1才缓存
unless: 否定缓存,当unless指定的条件为true,方法的返回值就不会缓存; 可以获取到结果进行判断
sync: 是否使用异步模式
key = "#id", condition = "#id>0", unless = "#result == null"
*/
@Cacheable(cacheNames = "emp", key = "#id")
public Employee getEmp(Integer id) {
System.out.println("查询" + id + "号员工");
return employeeMapper.getEmpById(id);
}
/*
@Cacheable运行流程:
1. 方法运行之前,查询Cache(缓存组件),按照cacheNames指定的name获取,CacheManager调用getCache(name)方法获取指定Cache
(第一次)如果为null,创建一个Cache,放入CacheMap中
2. 去Cache中查找缓存的内容,使用一个key(默认为方法参数)
key是按照某种策略生成的:(默认使用keyGenerator(SimpleKeyGenerator))keyGenerator.generate(this.target, this.metadata.method, this.args)
SimpleKeyGenerator默认的key生成策略:
如果有没有参数,返回SimpleKey: key = new SimpleKey()
如果有一个参数:直接返回该参数: key = 参数值
如果有多个参数:多个参数包装后全部返回: key = new SimpleKey(params)
3. 没有查到缓存,就调用目标方法;
4. 将目标方法缓存的结果放入缓存中(默认ConcurrentMap)
*/
//
//
// /*
// @CachePut:既调用方法,又更新缓存数据;修改了数据库的某个数据,同时更新缓存
// 运行时机:
// 1. 先调用目标方法
// 2. 将目标方法的结果缓存起来
//
// 测试步骤:
// 1、查询1号员工;查到的结果会放在缓存中;
// key:1 value:lastName:张三
// 2、以后查询还是之前的结果
// 3、更新1号员工;【lastName:zhangsan;gender:0】
// 将方法的返回值也放进缓存了;
// key:传入的employee对象 值:返回的employee对象;
// 4、查询1号员工?
// 应该是更新后的员工;
// key = "#employee.id":使用传入的参数的员工id;
// key = "#result.id":使用返回后的id
// */
@CachePut(cacheNames = "emp", key = "#employee.id")
public Employee updateEmp(Employee employee) {
System.out.println("updateEmp:" + employee);
employeeMapper.updateEmp(employee);
return employee;
}
//
// /*
// @CacheEvict: 缓存清除
// key:指定要清除的数据
// allEntries = true:指定清除这个缓存中所有的数据
// beforeInvocation = false:缓存的清除是否在方法之前执行
// 默认代表缓存清除操作是在方法执行之后执行;如果出现异常缓存就不会清除
// beforeInvocation = true:
// 代表清除缓存操作是在方法运行之前执行,无论方法是否出现异常,缓存都清除
//
// */
@CacheEvict(cacheNames = "emp", key = "#id")
public void deleteEmp(Integer id) {
System.out.println("deleteEMp:" + id);
// employeeMapper.deleteEmpById(id);
}
//
//
// // @Caching 定义复杂的缓存规则
// @Caching(
// cacheable = {
// @Cacheable(value = "emp", key = "#lastName")
// },
// put = {
// @CachePut(value = "emp", key = "#result.id"),
// @CachePut(value = "emp", key = "#result.email")
// }
// )
// public Employee getEmpByLastName(String lastName) {
// Employee employee = employeeMapper.getEmpByLastName(lastName);
// return employee;
// }
}
EmployeeController类:
package com.codel.cache.controller;
import com.codel.cache.pojo.Employee;
import com.codel.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.PostMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class EmployeeController {
@Autowired
EmployeeService employeeService;
@GetMapping("/emp/{id}")
public Employee getEmployee(@PathVariable("id") Integer id) {
return employeeService.getEmp(id);
// 测试成功,浏览器点击刷新,控制台只有第一次输出的数据 ,添加缓存成功
}
@PostMapping("/emp")
public Employee update(Employee employee) {
return employeeService.updateEmp(employee);
// 测试成功,修改数据后,就会自动更新缓存
}
//清除缓存
@GetMapping("/deleteEmp/{id}")
public String deleteEmp(@PathVariable("id") Integer id) {
employeeService.deleteEmp(id);
return "success";
}
//
// @GetMapping("/emp/lastname/{lastName}")
// public Employee getEmpByLastName(@PathVariable("lastName") String lastName){
// Employee emp = employeeService.getEmpByLastName(lastName);
// return emp;
// }
}
get方法查询,只会去数据库里面查询一次,刷新后只会从缓存里面获得数据