代码地址: https://download.youkuaiyun.com/download/zhanglinlang/11133435
spring boot cache 是spring 提供的一套缓存统计接口
只需要用这一套 缓存接口,下面可以兼容 redis ehcahe 实现对缓存的解耦。
spring boot cache 集成 redis 非常简单:
第一 导入 依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
第二步 在 Application类上 加上 缓存启动注解
@SpringBootApplication
@EnableCaching
public class CacheTestApplication {
第三步: 配置redis 数据库:
spring.redis.host=47.93.16.203
#端口号
spring.redis.port=6379
#如果有密码
spring.redis.password=irzhdredis
spring.redis.database=10
第四步:可以直接使用了:
@Service
@CacheConfig(cacheNames = "product") // cacheNames 代表redis 的一个map 对象。
public class ProductService {
@Autowired
private ProductMapper productMapper; //
/**
* spring Cache
* 注解方法介绍
* @Cacheable : (查询)有就获取缓存,没有就执行注解方法,并将结果缓存。
* @CachePut :(插入)将方法的结果缓存。
* @CacheEvict: (删除) 删除缓存
* @Caching : (复杂查询,可以将上面的三个方法组合使用)
*
* @Cacheable 和 @CachePut 参数介绍:
* key: 缓存key
* value: 缓存库。
* Condition (方法执行前调用): 条件判断: 如果条件为true 不会执行缓存方法(spel 表达式)
* Unless (方法执行后调用): 条件判断: 如果条件为true 不会执行缓存方法(spel 表达式)
*
* @CacheEvict: 参数介绍
* key value Condition 和前面一样。
* allEntries 条件判断: 如果为true 删除指定库(value)的所有缓存
* beforeInvocation 条件判断: 如果为true, 方法执行前删除, false 方法成功后删除
*
* SpEl 表达式:
* #root: 可以理解为当前注解的 方法反射对象。
* #root.args 当前方法的参数 (例如 root.args[0].name :获取第一个参数的 name 属性 ) 。
* #root.caches 该方法执行后对应的缓存数据 (例如 root.caches[0].id :获取第一个参数的 id 属性 ) 。
* #root.target
* #root.method
* #root.methodName
* #result 返回对象
* #result.id 返回对象的 id (当前对象必须有能够被访问到的 id 属性)
* #result.getName 返回对象名称。 (当前该对象必须有能够被访问到的 getName 方法名称。)
* #+参数名 : 获取参数值 例如 (int age,String name) 获取方式 #age #name
* #a+参数索引 :获取参数值 例如 (int age,String name) 获取方式 #a0 #a1
* #p+参数所有 :获取参数值 例如 (User user,Product p) 获取方式 #p0.id #p0.name
*/
/**
* Cacheable: 有就获取缓存,没有就执行下面的方法
* @param id
* @return
*/
@Cacheable(key = "#root.methodName+'['+#id+']'")
public Product getProductById(Long id) {
Product product = productMapper.getProductById(id);
System.out.println(product);
return product;
}
/**
* @CachePut 缓存插入,不检查缓存,只会将方法结果插入到缓存中
* value: 代表缓存名称, key 代表主键,
* p
* @param product
* @return
*/
@CachePut(key = "'getProductById'+'['+#p0.id+']'")
public Product updateProduct(Product product) {
int i = productMapper.updateProduct(product);
return product;
}
/**
* 删除缓存
* @param id
* @return
*/
@CacheEvict(value="product",key = "'getProductById'+'['+#id+']'")
public int deleteProductById(Long id) {
return productMapper.deleteProductById(id);
}
/**
* 删除缓存
* @return
*/
@CacheEvict(value="product",allEntries = true,beforeInvocation = true) //清除所有缓存
public void deleteProductAll() {
productMapper.deleteProduct();
}
//组合注解,可以完成各种骚操作。比如 (从A缓存,存在B缓存,并删除A缓存)
@Caching(
cacheable = {@Cacheable(value="product",key="#name")},
put = {
@CachePut(value="product",key="#result.id"),
@CachePut(value="product",key="#result.name")
}
)
public Product getProductByName(String productName) {
return productMapper.getProductByName(productName);
}
Mapper 模拟数据库,这里使用的是Map
@Component
public class ProductMapper {
LinkedHashMap<String, Product> map = new LinkedHashMap<>();
public Product getProductById(Long id) {
System.out.println("我是数据库");
return map.get(id);
}
public int updateProduct(Product product) {
System.out.println("我是数据库");
Product remove = map.remove(product.getId());
map.put(product.getId(), product);
if (remove != null) {
return 1;
}
return 0;
}
public int deleteProductById(Long id) {
System.out.println("我是数据库");
Product remove = map.remove(id);
return remove != null ? 1 : 0;
}
public Product getProductByName(String productName) {
System.out.println("我是数据库");
for (Iterator iterator = map.values().iterator(); iterator.hasNext(); ) {
Product next = (Product) iterator.next();
if (next.getName().equals(productName)) {
return next;
}
}
return null;
}
public void deleteProduct() {
System.out.println("我是数据库");
map.clear();
}
}
@Data
public class Product implements Serializable { //redis会将数据保存到硬盘,所有需要序列化对象
private String id;
private String name;
}
测试代码:
@RestController
public class ProductController {
/**
* 测试链接:
* http://localhost:8080/product?id=3&name=bbbbbbb
* http://localhost:8080/product/3
* http://localhost:8080/delproduct
*/
@Autowired
private ProductService productService;
@GetMapping("/product/{id}")
public Product getProduct(@PathVariable("id") Long id) {
Product product = productService.getProductById(id);
return product;
}
@GetMapping("/product")
public Product updateProduct(Product product) {
return productService.updateProduct(product);
}
@GetMapping("/delproduct/{id}")
public String delProduct(@PathVariable(value="id") Long id) {
productService.deleteProductById(id);
return "ok";
}
@GetMapping("/delproduct")
public String delProductAll() {
productService.deleteProductAll();
return "ok";
}
@GetMapping("/product/name/{productName}")
public Product getEmpByLastName(@PathVariable("productName") String productName){
return productService.getProductByName(productName);
}
}