Spring缓存篇之Spring抽象缓存实战

一,前言
本篇会从两个缓存讲起,分别是JSR-107缓存,Spring抽象缓存;
二,什么是JSR-107缓存
JSR是java Specification Requests的缩写,意思是Java 规范提案(2012年10月26日发布),JCache Api的首个早期提案,此次提案主要有哪些规范呢?

  • 定义了一种对java对象临时在内存中进行缓存的方法,一种对java对象临时在内存中进行缓存的方法,一种对java对象临时在内存中进行缓存的方法,重要事情说三遍。
  • 其中包括对象的创建,共享访问,失效,JVM一致性等,

JCache定义了Java标准的api。JCache主要定义了5个接口来规范缓存的生命周期

  • CachingProvider 创建,配置,获取,管理CacheManager
  • CacheManager 创建,配置,获取,管理Cache组件
  • Cache 类似于Map的数据结构,用来保存需要缓存的Entry
  • Entry 以K,V 键值对的形式来保存缓存数据
  • Expiry 过期机制,用来设置当前Entry是否过期

注:Cache缓存组件通过name唯一标识,且与CacheManager是一对一的关系

由于在实际的使用场景中,Spring抽象缓存用的多,这里就对JSR-107简单介绍,接下来中的看Spring抽象缓存

Spring抽象缓存

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

解析:
CacheManage:
缓存管理器,管理各种缓存组件
Cache:
缓存接口,定义缓存操作,实现的有RedisCache,EhCacheCache,ConcurrentMapCache等
Spring常用缓存注解:

  1. @Cacheable 针对方法的注解,默认根据方法的请求参数对该返回结果进行缓存
  2. @CacheEvict 清空缓存
  3. @CachePut 更新缓存,即使缓存中存在该请求结果,仍然会执行方法,并将缓存结果替换
  4. @EnableCaching 开启缓存,用在启动类上,开启缓存

以上对缓存的概念和常用注解都做了介绍,接下来就来实际演示一遍!

  1. 搭建数据库环境
  • 创建一个学生表student ,字段id,sname,age,gender并录入一些数据
  1. 创建对应的JavaBean
  2. 整合Mybatis,操作数据库
    1配置数据源信息&引入pom依赖
#数据源
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.url=jdbc:mysql://192.168.43.201/chen?serverTimezone=UTC
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
//为了后期便于观察,打印指定路径下的日志
logging.level.com.best.demobeststartertest.Cache.mapper=debug
  <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
          <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>

2编写对应的Mapper接口
并使用@Mapper注解该类

@Mapper    //在Mapper中实现查询方法
public interface StudentMapper {

    @Select("SELECT * from student where id=#{id}")
    public Student getStudentById(Integer id);

    @Delete("Delete  from student where id=#{id}")
    public boolean delStudentById(Integer id);

    @Insert("Insert into student values(#{id},#{sname},#{age},#{gender})")
    public boolean insetStu(Student student);
}

3编写对应的Service处理业务逻辑

@Service  //业务逻辑处理层
public class StudentService {

    @Autowired
    StudentMapper studentMapper;
//获取查询结果
    public Student getSt(Integer id){
        System.out.println("查询id为"+id+"的学生");
        Student student=studentMapper.getStudentById(id);
        return student;
    }
//插入数据
    public boolean InsertSt(Student student){
        boolean xx=studentMapper.insetStu(student);
        return xx;
    }
}

4编写Control控制台

@RestController
public class StudentControl {

    @Autowired
    StudentService studentService;
   //对该方法使用缓存
   /*
   解析一下此注解,主要有如下重要属性
   1 cacheNames:定义该缓存组件的名字。同时也是该组件的唯一标识,(缓存管理器就是通过缓存组件名称来进行管理)
   2 key 该缓存的key值,默认取值该方法的请求参数,例 #id
   3 keyGenerator key的生成策略,与key的作用相同,二者取其一
   4 condition 缓存的条件,满足该条件,才进行缓存
   5 unless 不缓存条件,满足该条件,不进行缓存,通常会通过#result==null,当方法返回值为空时,不进行缓存
   6 CacheManager 指定缓存管理器,即为当前的缓存组件指定唯一对应的管理器
   7 cacheResolver 缓存解析器,同样是对缓存进行管理,与CacheManager二者选其一
   8 sync  是否异步
   
   如下,我们给该缓存组件取名为xxxtent
    */
    @Cacheable(cacheNames="xxxtent")
    @RequestMapping("/Cache/getStudent/{id}") //将路径变量中取出Id占位符
    public Student getStudent(@PathVariable("id") Integer id){
      Student student=studentService.getSt(id);
      return student;
    }

    @RequestMapping("/Cache/InsertStuent")
    public boolean InsertStudent(Student student){
        boolean xx=studentService.InsertSt(student);
        return xx;
    }
}

5启动测试类,并查看控制台数据
第一次请求时,由于缓存中没有对应的数据,故执行方法

2020-02-02 17:33:50.104 DEBUG 1676 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : GET "/Cache/getStudent/8", parameters={}
2020-02-02 17:33:50.177 DEBUG 1676 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to com.best.demobeststartertest.Cache.Controller.StudentControl#getStudent(Integer)
查询id为8的学生

第二次发送同样请求,该缓存中存在对应数据,直接返回,不执行方法,故控制台未产生新数据

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章