@Cacheable
功能:将方法的运行结果进行缓存,以后再要相同数据,直接从缓存中获取,不用调用方法
属性:
- value/cacheNames:指定缓存的名字。cacheManager管理多个Cache组件,对缓存的真正操作在Cache组件中,每一个缓存组件有自己唯一一个名字。是数组的方式,可以指定多个缓存。
- key:缓存数据时用的key,默认是使用方法参数的值,可以使用SpEL。
- keyGenerator:key的生成器,可以自己指定key的生成器的组件id,key/keyGenerator二选一使用。
- cacheManager:指定缓存管理器,或者cacheResolver指定获取解析器。
- condition:指定符合条件情况下才缓存。
- unless:否定缓存,当unless指定的条件为true,方法的返回值就不会被缓存,可以获取到结果进行判断。
- sync:是否使用异步模式。
key和keyGenerator
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.qublog</groupId>
<artifactId>springboot09_cache</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot09_cache</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.3.0.RELEASE</spring-boot.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>8.0.12</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.properties
spring.datasource.url=jdbc:mysql://192.168.30.128:3306/spring_cache?serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
mybatis.configuration.map-underscore-to-camel-case=true
logging.level.com.qublog.cache.mapper=debug
#debug=true
Employee类:
package com.qublog.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 + "]";
}
}
EmployeeMapper接口:
package com.qublog.cache.mapper;
import com.qublog.cache.bean.Employee;
import org.apache.ibatis.annotations.*;
@Mapper
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 deleteEmp(Integer id);
@Insert("insert into employee(lastName,email,gender,d_id) values(#{lastName},#{email},#{gender},#{dId});")
public void insertEmp(Employee employee);
}
EmployeeService类:
package com.qublog.cache.service;
import com.qublog.cache.bean.Employee;
import com.qublog.cache.mapper.EmployeeMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
@Service
public class EmployeeService {
@Autowired
EmployeeMapper employeeMapper;
//将方法的运行结果进行缓存,以后再要相同数据,直接从缓存中获取,不用调用方法
//@Cacheable(cacheNames = {"emp"},key = "#root.methodName+'['+#id+']'")
@Cacheable(cacheNames = {"emp"},keyGenerator = "myKeyGenerator")
public Employee getEmp(Integer id){
System.out.println("查询"+id+"号员工");
Employee emp = employeeMapper.getEmpById(id);
return emp;
}
}
两种方法效果相同,二选一使用。
MyCacheConfig类:
package com.qublog.cache.config;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.lang.reflect.Method;
import java.util.Arrays;
@Configuration
public class MyCacheConfig {
@Bean("myKeyGenerator")
public KeyGenerator keyGenerator() {
return new KeyGenerator() {
@Override
public Object generate(Object o, Method method, Object... objects) {
return method.getName()+"["+ Arrays.asList(objects).toString() +"]";
}
};
}
}
EmployeeController类:
package com.qublog.cache.controller;
import com.qublog.cache.bean.Employee;
import com.qublog.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 getEmployee(@PathVariable("id") Integer id) {
Employee emp = employeeService.getEmp(id);
return emp;
}
}
Springboot09CacheApplication类:
package com.qublog.cache;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
/*
* 搭建基本环境:
* 1、导入数据库文件
* 2、创建javabean
* 3、整合mybatis
* 1、配置数据源
* 2、使用注解版mybatis
* 快速体验缓存:
* 步骤:
* 1、开启基于注解的缓存
* 2、标注缓存注解即可
* */
@EnableCaching
@MapperScan(value = {"com.qublog.cache.mapper"})
@SpringBootApplication
public class Springboot09CacheApplication {
public static void main(String[] args) {
SpringApplication.run(Springboot09CacheApplication.class, args);
}
}
condition
EmployeeService类:
package com.qublog.cache.service;
import com.qublog.cache.bean.Employee;
import com.qublog.cache.mapper.EmployeeMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
@Service
public class EmployeeService {
@Autowired
EmployeeMapper employeeMapper;
//将方法的运行结果进行缓存,以后再要相同数据,直接从缓存中获取,不用调用方法
//@Cacheable(cacheNames = {"emp"},key = "#root.methodName+'['+#id+']'")
//condition:第一个参数的值大于1的时候才进行缓存
@Cacheable(cacheNames = {"emp"},keyGenerator = "myKeyGenerator",condition = "#id>1")
public Employee getEmp(Integer id){
System.out.println("查询"+id+"号员工");
Employee emp = employeeMapper.getEmpById(id);
return emp;
}
}
访问http://localhost:8080/emp/1和http://localhost:8080/emp/2各两次:
可以看出只有id>1才进行缓存。
unless
EmployeeService类:
package com.qublog.cache.service;
import com.qublog.cache.bean.Employee;
import com.qublog.cache.mapper.EmployeeMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
@Service
public class EmployeeService {
@Autowired
EmployeeMapper employeeMapper;
//将方法的运行结果进行缓存,以后再要相同数据,直接从缓存中获取,不用调用方法
//@Cacheable(cacheNames = {"emp"},key = "#root.methodName+'['+#id+']'")
//condition:第一个参数的值大于1的时候才进行缓存
@Cacheable(cacheNames = {"emp"},keyGenerator = "myKeyGenerator",condition = "#id>1",unless = "#a0==2")
public Employee getEmp(Integer id){
System.out.println("查询"+id+"号员工");
Employee emp = employeeMapper.getEmpById(id);
return emp;
}
}
访问http://localhost:8080/emp/1和http://localhost:8080/emp/2各两次:
可以看出id为1和2都没有缓存。