5、Spring Boot缓存

2021-03-14 16:41

阅读:623

package com.hosystem.cache.service;

 

import com.hosystem.cache.bean.Employee;

import com.hosystem.cache.mapper.EmployeeMapper;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.cache.annotation.*;

import org.springframework.stereotype.Service;

 

@Service

@CacheConfig(cacheNames = "emp")

public class EmployeeService {

 

    @Autowired

    EmployeeMapper employeeMapper;

 

    /**

     *  将方法的运行结果进行缓存;下次在调用相同的数据,直接从缓存中获取,不再调用方法;

     *

     *  CacheManager管理多个cache组件,对缓存的真正CRUD操作在Cache组件中,每一个缓存组件有自己唯一一个名字

     *  工作原理:

     *      1.自动配置类:CacheAutoConfiguration

     *      2.缓存配置类:GenericCacheConfigurationJCacheCacheConfigurationEhCacheCacheConfigurationHazelcastCacheConfigurationInfinispanCacheConfigurationCouchbaseCacheConfigurationRedisCacheConfigurationCaffeineCacheConfigurationSimpleCacheConfigurationNoOpCacheConfiguration

     *          org.springframework.boot.autoconfigure.cache.GenericCacheConfiguration

     *          org.springframework.boot.autoconfigure.cache.JCacheCacheConfiguration

     *          org.springframework.boot.autoconfigure.cache.EhCacheCacheConfiguration

     *          org.springframework.boot.autoconfigure.cache.HazelcastCacheConfiguration

     *          org.springframework.boot.autoconfigure.cache.InfinispanCacheConfiguration

     *          org.springframework.boot.autoconfigure.cache.CouchbaseCacheConfiguration

     *          org.springframework.boot.autoconfigure.cache.RedisCacheConfiguration

     *          org.springframework.boot.autoconfigure.cache.CaffeineCacheConfiguration

     *          org.springframework.boot.autoconfigure.cache.SimpleCacheConfiguration

     *          org.springframework.boot.autoconfigure.cache.NoOpCacheConfiguration

     *      3.配置类默认生效:SimpleCacheConfiguration

     *      4.给容器中注册了一个cacheManager:ConcurrentMapCacheManager

     *      5.可以获取、创建ConcurrentMapCache类型的缓存组件;它的作用是将数据保存在ConcurrentMap

     *

     *  @Cacheable 运行流程:

     *      1.方法运行之前,先去查找Cache(缓存组件),按照cacheNames指定的名字获取;(CacheManager先获取相应的缓存)第一次获取缓存如果没有该缓存则会自动创建

     *      2.Cache中查找缓存的内容,使用一个key,默认为方法的参数;

     *        (1).key是按照某种策略生成的;默认是使用keyGenerator生成的,默认使用SimpleKeyGenerator生成key

     *        (2).默认使用SimpleKeyGenerator生成key默认策略:若无参数,key = new SimpleKey();|如果有单个参数,key=参数值;|如果有多个参数,key = new SimpleKey(params);

     *      3.若为查找到缓存就调用方法

     *      4.将方法返回的结果,放入缓存中

     *      @Cacheable 标注的方法执行之前先来检查缓存中有没有这个数据,默认按照参数的值作为key查找缓存,如果缓存不存在,则运行方法并将结果放入缓存

     *  核心:

     *      1.使用CacheManager[ConcurrentMapCacheManager]按照名字获取cache[ConcurrentHashMapCache]组件

     *      2.key使用keyGenerator生成,默认是SimpleKeyGenerator

     *

     *  属性:valuecacheNameskeykeyGeneratorcacheManagercacheResolverconditionunlesssync

     *      value/cacheNames:指定缓存组件的名字

     *      key:缓存数据使用的key,可以用它指定参数。默认是使用方法参数的值

     *          SpEL: #id:参数id的值  #a0 #p0 #root.args[0]

     *      keyGenerator:key生成器;可以指定key生成器组件id;

     *          注:keyGeneratorkey只能二选一

     *      cacheManager:指定缓存管理器

     *      cacheResolver:指定获取解析器

     *      condition:指定符合条件情况下缓存

     *      unless:否定缓存;unless指定条件为true,方法返回值不会被缓存;可以获取结果进行判断

     *      sync:是否使用异步模式

     */

    //cacheNames = "emp":

    //condition = "#id>0":只有当id>0的时候再进行缓存

    //condition = "#a0>1":只有当第一个参数>1时候才进行缓存

    //unless = "#result==null":当返回结果为空时不进行缓存

    //unless = "#a0==2":如果第一个参数的结果为2,则结果不缓存

    //key = "#root.methodName+‘[‘+#id+‘]‘"

    //keyGenerator = "myKeyGenerator":自定义key

    @Cacheable(cacheNames = "emp"/*,condition = "#a0>1",unless = "#a0==2"*/)

    public Employee getEmp(Integer id){

        System.out.println("查询"+id+"号员工");

        Employee emp = employeeMapper.getEmpById(id);

        return emp;

    }

 

    /**

     *  @CachePut:调用方法同时更新缓存数据

     *  修改数据库某个数据 同时更新缓存

     *

     *  运行时间:

     *    1.先调用方法

     *    2.将方法的结果缓存起来

     *

     *  测试步骤:

     *    1.查询1号员工;查询到的结果会放在缓存中 key:1 value:lastName:张三

     *    2.查询结果照旧

     *    3.更新1号员工信息[emp?id=1&lastName=zhangs&gender=0];将方法的返回值也放进缓存中 key:传入的employee对象 值:返回的employee对象

     *    4.查询1号员工;查询结果为未更新前的数据[1号员工的信息没有在缓存中更新]

     *      key = "#employee.id":使用传入参数的员工id进行更新

     *      key = "#result.id":使用返回后的id

     *      :@Cacheablekey是不能够使用#result

     */

    @CachePut(value = "emp",key = "#result.id")

    public Employee updateEmp(Employee employee){

        System.out.println("update" + employee);

        employeeMapper.updateEmp(employee);

        return employee;

    }

 

    /**

     *  @CacheEvict:缓存清除

     */

    //key = "#id":指定key删除缓存

    //allEntries = true:删除缓存中所有数据 默认参数为false

    //beforeInvocation=false:缓存的清除是否在方法之前执行 默认是false,即清除缓存操作在方法执行之后执行 如果方法出现异常缓存就不会清除

    //beforeInvocation = true:清除缓存操作在方法执行之前执行 如果方法出现异常缓存也会清除

    @CacheEvict(value = "emp"/*,key = "#id"*//*,allEntries = true*/,beforeInvocation = true)

    public void deleteEmp(Integer id){

        System.out.println("delete"+id);

//        employeeMapper.deleteEmpById(id);

        int i = 10/0;

    }

 

    @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){

        return employeeMapper.getEmpByLastName(lastName);

    }

}


评论


亲,登录后才可以留言!