Spring Boot(十三)Spring Boot中数据缓存的使用

你好,【程序职场】专注于:Spring Boot ,微服务 和 前端APP开发,闲暇之余一起聊聊职场规划,个人成长,还能带你一起探索 副业赚钱渠道,在提升技术的同时我们一起交流 敏捷流程 提高工作效率,从技术到管理一步步提升自我!
 
标签:一个执着的职场程序员!

本文是Spring Boot系列的第十三篇,了解前面的文章有助于更好的理解本文:


1.Spring Boot(一)初识Spring Boot框架
2.Spring Boot(二)Spring Boot基本配置
3.Spring Boot(三)Spring Boot自动配置的原理
4.Spring Boot(四)Spring Boot web项目开发
5.Spring Boot(五)Spring Boot web开发项目(2)配置
6.Spring Boot(六)Spring Boot web开发 SSL配置
7.Spring Boot(七)Spring Boot Websocket
8.Spring Boot(八)Spring Boot Websocket实现聊天功能
9.Spring Boot(九)Spring Boot Bootstrap和AngularJS的使用
10.Spring Boot(十)Spring Boot中使用JPA
11.Spring Boot(十一)Spring Boot中使用REST资源输出
12.Spring Boot(十二)Spring Boot中数据库事务的使用


前言

(一). Cache的介绍

(二). Cache注解

(三). Cache使用 实战

上篇文章为大家讲述了 Spring Boot中 数据库事务的使用;本篇文章接着上篇内容继续为大家介绍SpringBoot中 Cache的使用。

(一). Cache的介绍

Spring从3.1开始定义了org.springframework.cache.Cache和org.springframework.cache.CacheManager接口来统一不同的缓存技术;并支持使用JCache(JSR-107)注解简化我们开发;

  • Cache接口为缓存的组件规范定义,包含缓存的各种操作集合;

  • Cache接口下Spring提供了各种xxxCache的实现;如RedisCache,EhCacheCache ,ConcurrentMapCache等;

  • 每次调用需要缓存功能的方法时,Spring会检查检查指定参数的指定的目标方法是否已经被调用过;如果有就直接从缓存中获取方法调用后的结果,如果没有就调用方法并缓存结果后返回给用户。下次调用直接从缓存中获取。

  • 使用Spring缓存抽象时我们需要关注以下两点;

    1、确定方法需要被缓存以及他们的缓存策略

    2、从缓存中读取之前缓存存储的数据

(二). Cache注解
 

名称 解释
Cache 缓存接口,定义缓存操作。实现有:RedisCache、EhCacheCache、ConcurrentMapCache等
CacheManager 缓存管理器,管理各种缓存(cache)组件
@Cacheable 主要针对方法配置,能够根据方法的请求参数对其进行缓存
@CacheEvict 清空缓存
@CachePut 保证方法被调用,又希望结果被缓存。
与@Cacheable区别在于是否每次都调用方法,常用于更新
@EnableCaching 开启基于注解的缓存
keyGenerator 缓存数据时key生成策略
serialize 缓存数据时value序列化策略
@CacheConfig 统一配置本类的缓存注解的属性

@Cacheable/@CachePut/@CacheEvict 主要的参数

名称 解释
value 缓存的名称,在 spring 配置文件中定义,必须指定至少一个
例如:
@Cacheable(value=”mycache”) 或者
@Cacheable(value={”cache1”,”cache2”}
key 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,
如果不指定,则缺省按照方法的所有参数进行组合
例如:
@Cacheable(value=”testcache”,key=”#id”)
condition 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,
只有为 true 才进行缓存/清除缓存
例如:@Cacheable(value=”testcache”,condition=”#userName.length()>2”)
unless 否定缓存。当条件结果为TRUE时,就不会缓存。
@Cacheable(value=”testcache”,unless=”#userName.length()>2”)
allEntries
(@CacheEvict )
是否清空所有缓存内容,缺省为 false,如果指定为 true,
则方法调用后将立即清空所有缓存
例如:
@CachEvict(value=”testcache”,allEntries=true)
beforeInvocation
(@CacheEvict)
是否在方法执行前就清空,缺省为 false,如果指定为 true,
则在方法还没有执行的时候就清空缓存,缺省情况下,如果方法
执行抛出异常,则不会清空缓存
例如:
@CachEvict(value=”testcache”,beforeInvocation=true)


(三). Cache使用 实战

#创建项目
 

#数据库配置和依赖
这里的配置和前两篇文章中的一样,我这里不做过多说明了

数据库依赖:

<dependency>    <groupId>mysql</groupId>    <artifactId>mysql-connector-java</artifactId>    <version>5.1.40</version></dependency>

配置数据库和编码等:

spring.datasource.driver-class-name=com.mysql.jdbc.Driverspring.datasource.url=jdbc:mysql://localhost:3306/springbootcache?useUnicode=true&characterEncoding=utf-8spring.datasource.username=rootspring.datasource.password=root
spring.jpa.hibernate.ddl-auto=updatespring.jpa.show-sql=truespring.jackson.serialization.indent_output=true

#实体类添加

package org.myyoung.cxzc.springbootcache;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import java.io.Serializable;
@Entitypublic class Person{    @Id    @GeneratedValue    private Long id;    private String name;    private String detail;    private Integer time;    private String writer;
    public Long getId() {        return id;    }
    public void setId(Long id) {        this.id = id;    }
    public String getName() {        return name;    }
    public void setName(String name) {        this.name = name;    }
    public String getDetail() {        return detail;    }
    public void setDetail(String detail) {        this.detail = detail;    }
    public Integer getTime() {        return time;    }
    public void setTime(Integer time) {        this.time = time;    }
    public String getWriter() {        return writer;    }
    public void setWriter(String writer) {        this.writer = writer;    }
    public Person() {    }
    public Person(String name, String detail, Integer time, String writer) {        this.name = name;        this.detail = detail;        this.time = time;        this.writer = writer;    }}

这里强调一点,构造函数的添加
#实体类Repository

package org.myyoung.cxzc.springbootcache;import org.springframework.data.jpa.repository.JpaRepository;
public interface PersonRepository extends JpaRepository<Person,Long> {}

#业务服务模块
1. 业务接口

package org.myyoung.cxzc.springbootcache;public interface DemoService {    public Person save(Person person);    public void remove(Long id);    public Person findOne(Long id);}

三个接口,保存,删除,查询
2. 实现类

package org.myyoung.cxzc.springbootcache;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;import java.util.Optional;
@Servicepublic class DemoServiceImpl implements DemoService {    @Autowired    PersonRepository personRepository;
    @CachePut(value = "people", key = "#person.id")    @Override    public Person save(Person person) {        Person p = personRepository.save(person);        System.out.println("为id、key为" + p.getId() + "数据做了缓存");        return p;    }
    @CacheEvict(value = "people")    @Override    public void remove(Long id) {        System.out.println("删除了id、key为" + id + "的数据缓存");        personRepository.deleteById(id);    }
    @Cacheable(value = "people", key = "#id")    @Override    public Person findOne(Long id) {        Person p = personRepository.findById(id).get();        System.out.println("为id、key为" + p.getId() + "数据做了缓存");        return p;    }}

通过实现 上面的接口 做操作逻辑

1.@CachePut表示缓存新添加的数据或者更新的数据到缓存中,两个参数value表示缓存的名称为people,key表示缓存的key为person的id2.@CacheEvict表示从缓存people中删除key为id的数据3.@Cacheable表示添加数据到缓存中,缓存名称为people,缓存key为id属性。

#创建控制器

package org.myyoung.cxzc.springbootcache;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.*;
@RestController@RequestMapping("/person")public class CacheController {    @Autowired    DemoService demoService;
    @RequestMapping("/put")    public Person put(Person person) {        return demoService.save(person);    }
    @GetMapping("/able/{id}")    public Person cacheable(@PathVariable("id") Long id) {        return demoService.findOne(id);    }
    @DeleteMapping("/evit/{id}")    public String evit(@PathVariable("id") Long id) {        demoService.remove(id);        return "ok";    }}

#缓存的开启

package org.myyoung.cxzc.springbootcache;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cache.annotation.EnableCaching;
@EnableCaching@SpringBootApplicationpublic class SpringbootcacheApplication {
    public static void main(String[] args) {        SpringApplication.run(SpringbootcacheApplication.class, args);    }}

#运行效果 

首先看一下数据库信息:

1. 测试 Cacheable

Postman中第一次 访问   http://localhost:8080/person/able/1 调用查询数据库,并将数据放置到 缓存 people中结果显示
 


再次访问 此时控制台没有在输出 查询数据库的语句,以及提示缓存的信息,表示没有调用这个方法,页面直接通过环迅中获得数据

2. 测试 @CachePut

postman 访问 http://localhost:8080/person/put?name=测试1&detail=信息数据&time=10&id=4  插入数据:
如下图:

查看数据库,新增了一条信息。

再次访问  http://localhost:8080/person/able/4  控制台无任何信息输出,是直接从缓存中获得的数据。

3. 测试 @CacheEvict

首先 访问 http://localhost:8080/person/able/4 为 id = 4 的数据做缓存。操作,控制台会打印出来缓存的提示。

再次访问 http://localhost:8080/person/able/4  控制台无操作提示,确认数据是从缓存中获取的。

访问如下链接做 删除缓存操作:

http://localhost:8080/person/evit/4

界面效果如下:

此时再次访问 http://localhost:8080/person/able/4  观察控制台重新做缓存的提示操作。

ok,本篇内容到这里就完成了,如果小伙伴还有疑问,可以 关注我,我们一起进步

参考:
1. 《JavaEE开发的颠覆者 Spring Boot实战》

本案例下载地址:

https://github.com/ProceduralZC/itcxzc/tree/master/springbootcache

作者:小小蒲公英

猜你喜欢

转载自blog.csdn.net/jianpengxuexikaifa/article/details/104523405