springboot使用@EnableCaching实现缓存的使用

 

前言

1、先要开启缓存

@EnableCaching

开启缓存后,就要配置一个CacheManager的实现类,用于操作使用缓存注解后,用什么具体缓存实例来对缓存进行存储;

可以是基于内存的,也可以基于redis的;具体要怎么用,根据实际情况,一般工作场景redis大家走在用;

2、使用具体的缓存注解

@CachePut 使用@CachePut标注的方法在执行前不会去检查缓存中是否存在之前执行过的结果,而是每次都会执行该方法,并将执行结果以键值对的形式存入指定的缓存中。

@CacheEvict @CacheEvict是用来标注在需要清除缓存元素的方法或类上的。当标记在一个类上时表示其中所有的方法的执行都会触发缓存的清除操作。

@Cacheable Spring在每次执行前都会检查Cache中是否存在相同key的缓存元素,如果存在就不再执行该方法,而是直接从缓存中获取结果进行返回,否则才会执行并将返回结果存入指定的缓存中

 

项目中我们对于不易改动的信息没必要每次都去数据库查询,可以将查询结果放入缓存中,第二次调用时,直接在缓存中获取,不再经过数据库

1:配置cacheManager类

1、使用基于内存的缓存

@EnableCaching//开启缓存功能(如果你不开启,后面就算你使用了@Cacheable系列相关的缓存注解,也是没啥用的)
@Configuration
public class CacheConfig {
    

    //这种缓存是基于内存搞的(一般开发场景是使用的是redis缓存)
    @Bean
    public ConcurrentMapCacheManager cacheManager() {
        ConcurrentMapCacheManager cacheManager = new ConcurrentMapCacheManager();
        //cacheManager.setStoreByValue(true); //true表示缓存一份副本,否则缓存引用
        return cacheManager;
    }

}

2、使用基于redis的缓存

/**
 * 配置cache前缀和ttl时间
 */
@Bean
public RedisCacheManager redisCacheManager() {
    //connectionFactory:RedisConnectionFactory 是配置的redis连接工厂(获取连接后,就能操作redis数据库了)
    RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory);
    RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
            //prefix 配置缓存key的前缀(常用)这个是通过配置文件读取
            .prefixCacheNameWith(StrUtil.isEmpty(cacheProperties.getRedis().getKeyPrefix()) ? "" : cacheProperties.getRedis().getKeyPrefix() + ":")
            //ttl 配置全局的key有效时间
            .entryTtl(cacheProperties.getRedis().getTimeToLive() == null ? Duration.ZERO : cacheProperties.getRedis().getTimeToLive());
    return new RedisCacheManager(redisCacheWriter, redisCacheConfiguration);
}


2:缓存使用

缓存相关的

其他博主的总结(不明白就看)

@Cacheable(cacheNames = "studentCache", key = "#id")
@GetMapping("/get/one")
public Student getOneInfo(@RequestParam(value = "id",defaultValue = "")@ApiParam(value="主键id") Integer id){
    Student student=null;
    try {
        //int i=1/0;
        Date date=new Date();
        System.out.println("进行了查询---》"+ date.getTime());
        student= studentService.selectOne(id);
    } catch (Exception e) {
        throw ServiceException.zero_exception;
    }
    return student;
}
分析:
@Cacheable---------》开启缓存注解
studentCache---------》缓存名称
key---------》缓存的key值
方法的返回值---------》缓存的value值

通过查看缓存的信息可知,缓存放入成功:

@GetMapping("/get/cache")
@ApiOperation(value="查看缓存信息")
public String getCache(){
    Cache demoCache = cacheManager.getCache("studentCache");
    System.out.println(demoCache.getName());
    System.out.println(demoCache.get(1, Student.class));
    return demoCache.getName();
}
接下来,我们将缓存替换成redis缓存:

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;

import java.time.Duration;
import java.util.HashMap;
import java.util.Map;

@EnableCaching
@Configuration
public class CacheConfig {

    /*@Bean
    public ConcurrentMapCacheManager cacheManager() {
        ConcurrentMapCacheManager cacheManager = new ConcurrentMapCacheManager();
        //cacheManager.setStoreByValue(true); //true表示缓存一份副本,否则缓存引用
        return cacheManager;
    }*/

    /**
     * 最新版,设置redis缓存过期时间
     */

    @Bean
    public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
        return new RedisCacheManager(
                RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory),
                this.getRedisCacheConfigurationWithTtl( 60), // 默认策略,未配置的 key 会使用这个
                this.getRedisCacheConfigurationMap() // 指定 key 策略
        );
    }

    private Map getRedisCacheConfigurationMap() {
        Map redisCacheConfigurationMap = new HashMap<>();
        //SsoCache和BasicDataCache进行过期时间配置
        redisCacheConfigurationMap.put("messagCache", this.getRedisCacheConfigurationWithTtl(30 * 60));

        //自定义设置缓存时间
        redisCacheConfigurationMap.put("studentCache", this.getRedisCacheConfigurationWithTtl(60 ));

        return redisCacheConfigurationMap;
    }

    private RedisCacheConfiguration getRedisCacheConfigurationWithTtl(Integer seconds) {
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig();
        redisCacheConfiguration = redisCacheConfiguration.serializeValuesWith(
                RedisSerializationContext
                        .SerializationPair
                        .fromSerializer(jackson2JsonRedisSerializer)
        ).entryTtl(Duration.ofSeconds(seconds));

        return redisCacheConfiguration;
    }

}
使用RedisConnectionFactory 生成 cacheManager 对象,其余保持一致

controller:

@Cacheable(cacheNames = "studentCache", key = "#id")
@GetMapping("/get/one")
@ApiOperation(value="查询单条记录",notes = "查询")
//@ApiImplicitParam(name="id",defaultValue ="", value = "主键id",required = true,dataType ="Integer" )
public Student getOneInfo(@RequestParam(value = "id",defaultValue = "")@ApiParam(value="主键id") Integer id){
    Student student=null;
    try {
        //int i=1/0;
        Date date=new Date();
        System.out.println("进行了查询---》"+ date.getTime());
        student= studentService.selectOne(id);
    } catch (Exception e) {
        throw ServiceException.zero_exception;
    }
    return student;
}
查看缓存信息:

@GetMapping("/get/redis/cache")
@ApiOperation(value="查看redis缓存信息")
public String getRedisCache(){
    Cache demoCache = redisCacheManager.getCache("studentCache");
    System.out.println(demoCache.getName());
    System.out.println(demoCache.get(1, Student.class));
    return demoCache.getName();
}
调用查看缓存:

一分钟缓存时间到后,缓存清空:

学习参考:

https://mp.weixin.qq.com/s/UpTewC66iJyzq0osm_0cfw  江兰一点雨

 

你可能感兴趣的:(spring)