使用Springboot Cache做简单缓存

1、简单介绍

当我们需要展示数据的时候,后台会根据需要从服务器中获取数据,但是频繁的请求数据库会对服务造成压力,于是我们引入了缓存这个概念。

当我们引入缓存后,在调用一个缓存方法时,会根据相关信息和返回结果作为一个键值对存放在缓存中,等到下次利用同样的参数来调用该方法时将不再执行该方法,而是直接从缓存中获取结果进行返回,从而避免频繁访问数据库的情况。

2、基本注解

注解

解释

@EnableCaching

开启基于注解的缓存

@CacheConfig

统一配置本类的缓存注解的属性

@Cacheable

第一次调用方法后都将返回值存入缓存,下次则请求直接调用缓存

@CachePut

每次调用方法后都将返回值存入缓存,用于缓存更新

@CacheEvict

清除缓存

@Caching

组合注解,即给一个方法同时设置多个缓存方案

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

属性

解释

value/cacheNames

缓存区域的名称,必须指定至少一个

例如:

@Cacheable(value=”mycache”) 或者

@Cacheable(value={”cache1”,”cache2”}

key

缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,

如果不指定,则缺省按照方法的所有参数进行组合

例如:@Cacheable(key=”#id”)

condition

缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,

只有为 true 才进行缓存/清除缓存

例如:@Cacheable(condition=”#user != null”)

unless

当条件结果为TRUE时,就不会缓存。

例如@Cacheable(unless=”#user == null”)

allEntries

(@CacheEvict )

是否清空对应缓存区域所有缓存内容,默认为 false

beforeInvocation

(@CacheEvict)

是否在方法执行前就清空缓存,默认为 false,即如果方法没有执行完,或者抛出异常就不会清空缓存

3、使用

3.1 添加依赖

在springboot的pom文件添加如下依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>

3.2 启用注解

在启动类里添加@EnableCaching注解开启缓存

@EnableCaching//开启缓存
@MapperScan(basePackages = "com.huang.mapper")
@SpringBootApplication
public class SpringbootCacheApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootCacheApplication.class, args);
    }

}
@EnableCaching//开启缓存
@MapperScan(basePackages = "com.huang.mapper")
@SpringBootApplication
public class SpringbootCacheApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootCacheApplication.class, args);
    }

}
注意:默认提供的缓存实现方式是map集合

3.3 使用缓存

3.3.1 在要缓存结果的方法上添加@Cacheabl注解
/*
    * @Cacheabl
    * 开启缓存,将方法结果存入缓存,再次请求同样的数据时直接从缓存中调用,不再调用方法
    * 属性:
    *   value/cacheName:指定缓存名字
    *   key:指定缓存数据的键值对的key,默认为方法参数中的值
    *        也可用sqEl表达式
    *   Condition:指定缓存执行的条件
    *   unliss:指定缓存不执行的条件
    *   sync:指定缓存是否使用异步模式,默认同步,若异步则不支持unless
    * */
    @Override
    @Cacheable(cacheNames = "dept",key = "targetClass")
    public List<Dept> findAll() {
        System.out.println("全查!");
        return mapper.selectAll();
    }
/*
    * @Cacheabl
    * 开启缓存,将方法结果存入缓存,再次请求同样的数据时直接从缓存中调用,不再调用方法
    * 属性:
    *   value/cacheName:指定缓存名字
    *   key:指定缓存数据的键值对的key,默认为方法参数中的值
    *        也可用sqEl表达式
    *   Condition:指定缓存执行的条件
    *   unliss:指定缓存不执行的条件
    *   sync:指定缓存是否使用异步模式,默认同步,若异步则不支持unless
    * */
    @Override
    @Cacheable(cacheNames = "dept",key = "targetClass")
    public List<Dept> findAll() {
        System.out.println("全查!");
        return mapper.selectAll();
    }


3.3.2 在要更新缓存的方法上添加@CachePut注解
/*
    * @CachePut
    * 调用方法后,再把返回值放入缓存
    * 属性与cacheable基本相同
    * 由于总是执行方法后才操作缓存,在key等属性可以调用#result返回值
    * 设置key与@cachable相同可以重写缓存里的数据
    * */
    @Override
    @CachePut(cacheNames = "dept",key = "#root.targetClass")
    public List<Dept> add(Dept dept) {
        System.out.println("增加!");
        mapper.insert(dept);
        return mapper.selectAll();
    }
/*
    * @CachePut
    * 调用方法后,再把返回值放入缓存
    * 属性与cacheable基本相同
    * 由于总是执行方法后才操作缓存,在key等属性可以调用#result返回值
    * 设置key与@cachable相同可以重写缓存里的数据
    * */
    @Override
    @CachePut(cacheNames = "dept",key = "#root.targetClass")
    public List<Dept> add(Dept dept) {
        System.out.println("增加!");
        mapper.insert(dept);
        return mapper.selectAll();
    }


3.3.3 在要更新缓存的方法上添加@CachePut注解
/*
    * @CacheEvict
    * 清除缓存中的数据
    * beforeInvocation
    * 默认值为false,即默认清除缓存在方法后执行,若出现异常则缓存不清除。为true则相反
    * */
    @CacheEvict(cacheNames = "dept",key = "#root.targetClass",beforeInvocation = false)
    @Override
    public void delete(Integer deptno) {
        System.out.println("删除!");
        mapper.deleteByPrimaryKey(deptno);
    }
/*
    * @CacheEvict
    * 清除缓存中的数据
    * beforeInvocation
    * 默认值为false,即默认清除缓存在方法后执行,若出现异常则缓存不清除。为true则相反
    * */
    @CacheEvict(cacheNames = "dept",key = "#root.targetClass",beforeInvocation = false)
    @Override
    public void delete(Integer deptno) {
        System.out.println("删除!");
        mapper.deleteByPrimaryKey(deptno);
    }
3.3.4 在有复杂缓存策略的方法上添加@Caching注解
/*
    * @caching
    * 组合注解,三种注解以每种可有多个,以数组形式存储
    * */
    @Caching(
            cacheable = {
                //添加一个缓存
                @Cacheable(value = "dept",key = "#deptno")
            },
            put = {
                //更新一个缓存
                @CachePut(value = "emp",key = "#root.targetClass")
            },
            evict = {
                //清除一个缓存
                @CacheEvict(value = "person",key = "#deptno")
            }
    )
    @Override
    public Dept findById(Integer deptno) {
        return null;
    }
/*
    * @caching
    * 组合注解,三种注解以每种可有多个,以数组形式存储
    * */
    @Caching(
            cacheable = {
                //添加一个缓存
                @Cacheable(value = "dept",key = "#deptno")
            },
            put = {
                //更新一个缓存
                @CachePut(value = "emp",key = "#root.targetClass")
            },
            evict = {
                //清除一个缓存
                @CacheEvict(value = "person",key = "#deptno")
            }
    )
    @Override
    public Dept findById(Integer deptno) {
        return null;
    }
3.3.5 当一个类里多个方法的缓存有重复配置,可以在类上使用@CacheConfig注解
//使用@CacheConfig统一cacheName,如果在方法上仍写了value,则该方法值仍以value为准
@CacheConfig(cacheNames = "dept")
@Service
public class DeptServiceImp implements DeptService {

    @Resource
    private DeptMapper mapper;
    
    @Override
    @Cacheable(key = "targetClass")
    public List<Dept> findAll() {
        System.out.println("全查!");
        return mapper.selectAll();
    }
    
    @Override
    @CachePut(key = "targetClass")
    public List<Dept> add(Dept dept) {
        System.out.println("增加!");
        mapper.insert(dept);
        return mapper.selectAll();
    }

    @CachePut(key = "targetClass")
    @Override
    public List<Dept> delete(Integer deptno) {
        System.out.println("删除!");
        mapper.deleteByPrimaryKey(deptno);
        return mapper.selectAll();
    }


}
//使用@CacheConfig统一cacheName,如果在方法上仍写了value,则该方法值仍以value为准
@CacheConfig(cacheNames = "dept")
@Service
public class DeptServiceImp implements DeptService {

    @Resource
    private DeptMapper mapper;
    
    @Override
    @Cacheable(key = "targetClass")
    public List<Dept> findAll() {
        System.out.println("全查!");
        return mapper.selectAll();
    }
    
    @Override
    @CachePut(key = "targetClass")
    public List<Dept> add(Dept dept) {
        System.out.println("增加!");
        mapper.insert(dept);
        return mapper.selectAll();
    }

    @CachePut(key = "targetClass")
    @Override
    public List<Dept> delete(Integer deptno) {
        System.out.println("删除!");
        mapper.deleteByPrimaryKey(deptno);
        return mapper.selectAll();
    }


}