【springboot】缓存之@Cacheable、@CachePut、@CacheEvict的用法
作者:mmseoamin日期:2023-12-13

目录

        • 一、注解参数说明
          • 1.1 属性说明
            • 1.1.1 value/cacheNames 属性
            • 1.1.2 key属性
            • 1.1.3 keyGenerator属性
            • 1.1.4 cacheManager属性
            • 1.1.5 cacheResolver属性
            • 1.1.6 condition属性
            • 1.1.7 unless 属性
            • 1.1.8 sync 属性
            • 1.2 @Cacheable注解
            • 1.3 @CachePut注解
            • 1.4 @CacheEvict注解
              • 1.4.1 allEntries属性
              • 1.4.2 beforeInvocation属性
              • 二、代码示例
                • 2.1 基本框架搭建
                • 2.2 value属性与cacheNames属性
                  • 2.2.1 单个缓存代码示例
                  • 2.2.2 单个缓存效果截图
                  • 2.2.3 多个缓存代码示例
                  • 2.2.4 多个缓存效果截图
                  • 2.3 key属性
                    • 2.3.1 方法没有参数示例
                    • 2.3.2 方法没有参数截图
                    • 2.3.3 方法有一个参数示例
                    • 2.3.4 方法有一个参数截图
                    • 2.3.5 方法有多个参数示例
                    • 2.3.6 方法有多个参数截图
                    • 2.3.7 指定key(从参数中指定)
                    • 2.3.8 指定key截图
                    • 2.4 keyGenerator属性
                      • 2.4.1 自定义key生成器代码示例
                      • 2.4.2 自定义key生成器截图
                      • 2.5 cacheResolver属性
                        • 2.5.1 自定义cacheResolver缓存解析器代码示例
                        • 2.5.2 自定义cacheResolver缓存解析器截图
                        • 2.6 condition属性
                          • 2.6.1 指定条件进行缓存代码示例
                          • 2.6.2 指定条件进行缓存截图
                          • 2.7 unless属性
                            • 2.7.1 指定条件不进行缓存代码示例
                            • 2.7.2 结果为null的缓存截图
                            • 2.8 allEntries属性
                              • 2.8.1 清除全部缓存代码示例
                              • 2.8.2 先查2次缓存起来,然后删除1条,清除所有截图
                              • 三、注意事项
                                一、注解参数说明
                                1.1 属性说明
                                1.1.1 value/cacheNames 属性
                                • 1.这两个属性代表的意义相同
                                • 2.用来指定缓存组件的名称,将方法的返回结果存进缓存的名称
                                • 3.定义为数组时,可以存到多个缓存key中
                                  1.1.2 key属性
                                  • 1.指定缓存数据的key
                                    1.#root.method.name:当前被调用的方法名
                                    2.#root.methodName:当前被调用的方法
                                    3.#root.target:当前被调用的目标对象
                                    4.#root.targetClass:当前被调用的目标对象类
                                    5.#root.args[0]:当前被调用的方法的参数列表
                                    6.#root.caches[0].name:当前方法调用使用的缓存列表(@Cacheable(value={"cache1","cache2"}))
                                    7.#id、#p0、#a0:方法参数的名字,可以#参数名,也可以使用 #p0或#a0 的形式,0代表参数的索引
                                    8.#result:方法执行后的返回值(仅当方法执行之后的判断有效,如’unless’、@cacheput和@cacheevict的表达式beforeInvocation=false)
                                    
                                    • 2.redis作为缓存时,redis中的key为value::key
                                    • 3.方法没有参数时,key=new SimpleKey()
                                    • 4.方法有一个参数时,key=参数的值
                                    • 5.方法有多个参数时,key=new SimpleKey(params);
                                      1.1.3 keyGenerator属性
                                      • 1.key 的生成器
                                      • 2.可以自定义key的生成器的组件id
                                      • 3.key与keyGenerator二选一使用
                                      • 4.可以自定义配置类,将 keyGenerator 注册到 IOC 容器
                                        1.1.4 cacheManager属性
                                        • 1.用来指定缓存管理器
                                        • 2.对不同的缓存技术,实现不同的cacheManager,spring定义了一些 cacheManger的实现
                                        • 3.SimpleCacheManager:使用简单的Collection来存储缓存(默认)
                                        • 4.ConcurrentMapCacheManager:使用ConcurrentMap作为缓存技术
                                        • 5.NoOpCacheManager:测试用
                                        • 6.EhCacheCacheManager:使用EhCache作为缓存技术,hibernate经常用
                                        • 7.GuavaCacheManager:使用google的guava的GuavaCache作为缓存技术
                                        • 8.HazelcastCacheManager:使用Hazelcast作为缓存技术
                                        • 9.JCacheCacheManager:使用JCache标准的实现作为缓存技术,如Apache Commons JCS
                                        • 10.RedisCacheManager:使用Redis作为缓存技术
                                          1.1.5 cacheResolver属性
                                          • 1.指定自定义的缓存管理器
                                          • 2.cacheManager缓存管理器与cacheResolver自定义解析器二选一使用
                                            1.1.6 condition属性
                                            • 1.符合指定的条件才可以缓存
                                            • 2.可以通过 SpEL 表达式进行设置
                                              1.1.7 unless 属性
                                              • 1.unless的条件为 true 时,方法的返回值不会被缓存
                                              • 2.可以在获取到结果后进行判断
                                                1.1.8 sync 属性
                                                • 1.是否使用同步模式
                                                • 2.异步模式下 unless 属性不可用
                                                • 3.sync=true:同步模式,若多个线程尝试为同一个key缓存值,当一个线程缓存成功后,其它线程便直接拿缓存后的数据,不会再去查库缓存,能解决缓存击穿问题;一个线程去新建,新建成功后其它线程才能拿
                                                • 4.默认是false
                                                  1.2 @Cacheable注解
                                                  • 1.每次执行方法前都会检查cache中是否存在相同key的缓存,如果存在就不再执行该方法,直接从缓存中获取结果进行返回,如果不存在则会执行该方法并将结果存入指定key的缓存中
                                                    1.3 @CachePut注解
                                                    • 1.在执行方法前不会去检查缓存中是否存在key的缓存,每次都会执行该方法,并将执行结果存入指定key的缓存中
                                                    • 2.使用在保存,更新方法中
                                                    • 3.标注在类上和方法
                                                      1.4 @CacheEvict注解
                                                      • 1.标注在需要清除缓存的方法或类
                                                      • 2.标记在类上时表示其中所有方法的执行都会触发缓存的清除操作
                                                      • 3.@CacheEvict可以指定的属性有value、key、condition、allEntries和beforeInvocation
                                                        1.4.1 allEntries属性
                                                        • 1.allEntries为true时,清除value属性值中的所有缓存,更有效率
                                                        • 2.默认为false,可以指定清除value属性值下具体某个key的缓存
                                                          1.4.2 beforeInvocation属性
                                                          • 1.默认是false,即在方法执行成功后触发删除缓存的操作
                                                          • 2.如果方法抛出异常未能成功返回,不会触发删除缓存的操作
                                                          • 3.当改为true时,方法执行之前会清除指定的缓存,这样不论方法执行成功还是失败都会清除缓存
                                                            二、代码示例
                                                            2.1 基本框架搭建
                                                            • 1.导入依赖
                                                              
                                                              
                                                                  
                                                                      springboot-learning
                                                                      com.learning
                                                                      1.0-SNAPSHOT
                                                                  
                                                                  4.0.0
                                                                  springboot-cache
                                                                  
                                                                      8
                                                                      8
                                                                  
                                                                  
                                                                      
                                                                      
                                                                          org.springframework.boot
                                                                          spring-boot-starter-web
                                                                      
                                                                      
                                                                          org.springframework.boot
                                                                          spring-boot-starter-test
                                                                      
                                                                      
                                                                      
                                                                          com.baomidou
                                                                          mybatis-plus-boot-starter
                                                                          3.4.2
                                                                      
                                                                      
                                                                      
                                                                          mysql
                                                                          mysql-connector-java
                                                                          runtime
                                                                      
                                                                      
                                                                      
                                                                          org.springframework.boot
                                                                          spring-boot-starter-cache
                                                                      
                                                                      
                                                                      
                                                                          org.springframework.boot
                                                                          spring-boot-starter-data-redis
                                                                      
                                                                  
                                                              
                                                              
                                                              • 2.application.yaml配置
                                                                spring:
                                                                  datasource:
                                                                    url: jdbc:mysql://localhost:3306/test?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=false
                                                                    driver-class-name: com.mysql.cj.jdbc.Driver
                                                                    username: root
                                                                    password: root
                                                                  cache:
                                                                    type: redis
                                                                  redis:
                                                                    host: 127.0.0.1
                                                                    port: 6379
                                                                mybatis-plus:
                                                                  global-config:
                                                                    db-config:
                                                                      id-type: auto
                                                                  configuration:
                                                                    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
                                                                
                                                                • 3.接口类
                                                                  package com.learning.cache.controller;
                                                                  import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
                                                                  import com.learning.cache.entity.Student;
                                                                  import com.learning.cache.service.StudentService;
                                                                  import org.springframework.beans.factory.annotation.Autowired;
                                                                  import org.springframework.web.bind.annotation.*;
                                                                  import java.util.List;
                                                                  /**
                                                                   * @Description 接口类
                                                                   */
                                                                  @RestController
                                                                  @RequestMapping("student")
                                                                  public class StudentController {
                                                                      @Autowired
                                                                      private StudentService studentService;
                                                                      @ResponseBody
                                                                      @GetMapping("/list")
                                                                      public List getList(){
                                                                          return studentService.list();
                                                                      }
                                                                      @ResponseBody
                                                                      @GetMapping("/{id}")
                                                                      public Student getById(@PathVariable String id){
                                                                          return studentService.getById(id);
                                                                      }
                                                                      @ResponseBody
                                                                      @GetMapping("/page")
                                                                      public Page getPage(@RequestParam int size, @RequestParam int current){
                                                                          return studentService.page(size, current);
                                                                      }
                                                                      @ResponseBody
                                                                      @PostMapping("/save")
                                                                      public Student save(@RequestBody Student student){
                                                                          return studentService.save(student);
                                                                      }
                                                                      @DeleteMapping("/{id}")
                                                                      public boolean delete(@PathVariable String id){
                                                                          return studentService.delete(id);
                                                                      }
                                                                  }
                                                                  
                                                                  • 4.service实现类
                                                                    package com.learning.cache.service.impl;
                                                                    import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
                                                                    import com.learning.cache.dao.StudentDao;
                                                                    import com.learning.cache.entity.Student;
                                                                    import com.learning.cache.service.StudentService;
                                                                    import org.springframework.beans.factory.annotation.Autowired;
                                                                    import org.springframework.cache.annotation.CacheEvict;
                                                                    import org.springframework.cache.annotation.Cacheable;
                                                                    import org.springframework.stereotype.Service;
                                                                    import java.util.List;
                                                                    /**
                                                                     * @Description 学生服务实现类
                                                                     */
                                                                    @Service
                                                                    public class StudentServiceImpl implements StudentService {
                                                                        @Autowired
                                                                        private StudentDao studentDao;
                                                                        @Cacheable(value={"com:learning:cache:list"})
                                                                        @Override
                                                                        public List list() {
                                                                            return studentDao.selectList(null);
                                                                        }
                                                                        @Cacheable(value="com:learning:cache:one")
                                                                        @Override
                                                                        public Student getById(String id) {
                                                                            return studentDao.selectById(id);
                                                                        }
                                                                        @Cacheable(value={"com:learning:cache:more"})
                                                                        @Override
                                                                        public Page page(int size, int current) {
                                                                            Page page = new Page<>();
                                                                            page.setCurrent(current);
                                                                            page.setSize(size);
                                                                            return studentDao.selectPage(page, null);
                                                                        }
                                                                        @Override
                                                                        public Student save(Student student) {
                                                                            int result = studentDao.insert(student);
                                                                            if(result > 0){
                                                                                return student;
                                                                            }
                                                                            return null;
                                                                        }
                                                                        @CacheEvict(value="com:learning:cache:one", allEntries = true)
                                                                        @Override
                                                                        public boolean delete(String id) {
                                                                            int result = studentDao.deleteById(id);
                                                                            if(result > 0){
                                                                                return true;
                                                                            }
                                                                            return false;
                                                                        }
                                                                    }
                                                                    
                                                                    • 5.service接口类
                                                                      package com.learning.cache.service;
                                                                      import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
                                                                      import com.learning.cache.entity.Student;
                                                                      import java.util.List;
                                                                      public interface StudentService {
                                                                          List list();
                                                                          Student getById(String id);
                                                                          Page page(int size, int current);
                                                                          Student save(Student student);
                                                                          boolean delete(String id);
                                                                      }
                                                                      
                                                                      • 6.持久层类
                                                                        package com.learning.cache.dao;
                                                                        import com.baomidou.mybatisplus.core.mapper.BaseMapper;
                                                                        import com.learning.cache.entity.Student;
                                                                        import org.apache.ibatis.annotations.Mapper;
                                                                        /**
                                                                         * @Description 学生持久层类
                                                                         */
                                                                        @Mapper
                                                                        public interface StudentDao extends BaseMapper {
                                                                        }
                                                                        
                                                                        • 7.启动类
                                                                          package com.learning.cache;
                                                                          import org.springframework.boot.SpringApplication;
                                                                          import org.springframework.boot.autoconfigure.SpringBootApplication;
                                                                          import org.springframework.cache.annotation.EnableCaching;
                                                                          /**
                                                                           * @Description 启动类
                                                                           */
                                                                          @SpringBootApplication
                                                                          // 开启启用缓存注解
                                                                          @EnableCaching
                                                                          public class Application {
                                                                              public static void main(String[] args) {
                                                                                  SpringApplication.run(Application.class, args);
                                                                              }
                                                                          }
                                                                          
                                                                          • 8.配置类
                                                                            package com.learning.cache.config;
                                                                            import com.learning.cache.resolver.CustomCacheResolver;
                                                                            import org.springframework.cache.interceptor.CacheResolver;
                                                                            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.connection.RedisConnectionFactory;
                                                                            /**
                                                                             * @Description 自定义Key生成器
                                                                             */
                                                                            @Configuration
                                                                            public class CacheResolverConfig {
                                                                                @Bean
                                                                                public RedisCacheManager redisCacheManager(RedisConnectionFactory redisConnectionFactory) {
                                                                                    RedisCacheConfiguration cacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
                                                                                            .computePrefixWith(cacheName -> cacheName.concat(":"));
                                                                                    return RedisCacheManager.builder(redisConnectionFactory)
                                                                                            .cacheDefaults(cacheConfiguration)
                                                                                            .build();
                                                                                }
                                                                                @Bean("customCacheResolver")
                                                                                public CacheResolver customCacheResolver(RedisConnectionFactory redisConnectionFactory) {
                                                                                    return new CustomCacheResolver(redisCacheManager(redisConnectionFactory));
                                                                                }
                                                                            }
                                                                            
                                                                            package com.learning.cache.config;
                                                                            import org.apache.ibatis.executor.Executor;
                                                                            import org.apache.ibatis.mapping.MappedStatement;
                                                                            import org.springframework.cache.interceptor.KeyGenerator;
                                                                            import org.springframework.context.annotation.Bean;
                                                                            import org.springframework.context.annotation.Configuration;
                                                                            import java.lang.reflect.Method;
                                                                            import java.util.Arrays;
                                                                            import java.util.UUID;
                                                                            /**
                                                                             * @Description 自定义Key生成器
                                                                             */
                                                                            @Configuration
                                                                            public class KeyGeneratorConfig {
                                                                                @Bean("customKeyGenerator")
                                                                                public KeyGenerator keyGenerator(){
                                                                                    return new KeyGenerator() {
                                                                                        @Override
                                                                                        public Object generate(Object o, Method method, Object... objects) {
                                                                                            return method.getName() + Arrays.asList(objects).toString() + UUID.randomUUID();
                                                                                        }
                                                                                    };
                                                                                }
                                                                            }
                                                                            
                                                                            package com.learning.cache.config;
                                                                            import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
                                                                            import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
                                                                            import org.springframework.context.annotation.Bean;
                                                                            import org.springframework.context.annotation.Configuration;
                                                                            /**
                                                                             * @Description 分页配置类
                                                                             */
                                                                            @Configuration
                                                                            public class MybatisPlusConfig {
                                                                                @Bean
                                                                                public MybatisPlusInterceptor mybatisPlusInterceptor(){
                                                                                    MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
                                                                                    interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
                                                                                    return interceptor;
                                                                                }
                                                                            }
                                                                            
                                                                            package com.learning.cache.resolver;
                                                                            import lombok.extern.slf4j.Slf4j;
                                                                            import org.springframework.cache.Cache;
                                                                            import org.springframework.cache.CacheManager;
                                                                            import org.springframework.cache.interceptor.*;
                                                                            import org.springframework.context.expression.MethodBasedEvaluationContext;
                                                                            import org.springframework.core.DefaultParameterNameDiscoverer;
                                                                            import org.springframework.core.ParameterNameDiscoverer;
                                                                            import org.springframework.expression.EvaluationContext;
                                                                            import org.springframework.expression.Expression;
                                                                            import org.springframework.expression.spel.standard.SpelExpressionParser;
                                                                            import java.lang.reflect.Method;
                                                                            import java.util.Collection;
                                                                            /**
                                                                             * @Description 自定义缓存解析器
                                                                             */
                                                                            @Slf4j
                                                                            public class CustomCacheResolver extends SimpleCacheResolver {
                                                                                public CustomCacheResolver(CacheManager cacheManager) {
                                                                                    super(cacheManager);
                                                                                }
                                                                                @Override
                                                                                public Collection resolveCaches(CacheOperationInvocationContext context) {
                                                                                    // 拿到缓存
                                                                                    Collection caches = super.resolveCaches(context);
                                                                                    Object target = context.getTarget();
                                                                                    BasicOperation operation = context.getOperation();
                                                                                    Method method = context.getMethod();
                                                                                    Object[] args = context.getArgs();
                                                                                    ParameterNameDiscoverer paramNameDiscoverer = new DefaultParameterNameDiscoverer();
                                                                                    EvaluationContext evaluationContext = new MethodBasedEvaluationContext(context.getOperation(), context.getMethod(), context.getArgs(), paramNameDiscoverer);
                                                                                    Expression expression = (new SpelExpressionParser()).parseExpression(((CacheableOperation) context.getOperation()).getKey());
                                                                                    // 获取所有的缓存的名字
                                                                                    context.getOperation().getCacheNames().forEach(cacheName -> {
                                                                                        log.info("缓存的name:{}", cacheName);
                                                                                        String key = cacheName + ':' + expression.getValue(evaluationContext, String.class);
                                                                                        log.info("缓存的key全路径:{}", key);
                                                                                    });
                                                                                    // 返回缓存
                                                                                    return caches;
                                                                                }
                                                                            }
                                                                            
                                                                            • 10.实体类
                                                                              package com.learning.cache.entity;
                                                                              import lombok.Data;
                                                                              import java.io.Serializable;
                                                                              /**
                                                                               * @Description 学生类
                                                                               */
                                                                              @Data
                                                                              // 要实现Serializable接口,否则会报错
                                                                              public class Student implements Serializable {
                                                                                  private String id;
                                                                                  private String name;
                                                                                  private Integer age;
                                                                              }
                                                                              
                                                                              2.2 value属性与cacheNames属性
                                                                              2.2.1 单个缓存代码示例
                                                                              package com.learning.cache.service.impl;
                                                                              import com.learning.cache.dao.StudentDao;
                                                                              import com.learning.cache.entity.Student;
                                                                              import com.learning.cache.service.StudentService;
                                                                              import org.springframework.beans.factory.annotation.Autowired;
                                                                              import org.springframework.cache.annotation.Cacheable;
                                                                              import org.springframework.stereotype.Service;
                                                                              import java.util.List;
                                                                              /**
                                                                               * @Description 学生服务实现类
                                                                               */
                                                                              @Service
                                                                              public class StudentServiceImpl implements StudentService {
                                                                                  @Autowired
                                                                                  private StudentDao studentDao;
                                                                              	// com:learning:cache会作为redis的key的一部分
                                                                                  @Cacheable(value="com:learning:cache:list")
                                                                                  @Override
                                                                                  public List list() {
                                                                                      return studentDao.selectList(null);
                                                                                  }
                                                                              }
                                                                              
                                                                              2.2.2 单个缓存效果截图

                                                                              【springboot】缓存之@Cacheable、@CachePut、@CacheEvict的用法,在这里插入图片描述,第1张

                                                                              2.2.3 多个缓存代码示例
                                                                              package com.learning.cache.service.impl;
                                                                              import com.learning.cache.dao.StudentDao;
                                                                              import com.learning.cache.entity.Student;
                                                                              import com.learning.cache.service.StudentService;
                                                                              import org.springframework.beans.factory.annotation.Autowired;
                                                                              import org.springframework.cache.annotation.Cacheable;
                                                                              import org.springframework.stereotype.Service;
                                                                              import java.util.List;
                                                                              /**
                                                                               * @Description 学生服务实现类
                                                                               */
                                                                              @Service
                                                                              public class StudentServiceImpl implements StudentService {
                                                                                  @Autowired
                                                                                  private StudentDao studentDao;
                                                                              	// 多个值,会将方法的返回结果存入到不同的缓存key中
                                                                                  @Cacheable(value={"com:learning:cache:list","cn:learning:cache:list"})
                                                                                  @Override
                                                                                  public List list() {
                                                                                      return studentDao.selectList(null);
                                                                                  }
                                                                              }
                                                                              
                                                                              2.2.4 多个缓存效果截图

                                                                              【springboot】缓存之@Cacheable、@CachePut、@CacheEvict的用法,在这里插入图片描述,第2张

                                                                              2.3 key属性
                                                                              2.3.1 方法没有参数示例
                                                                              package com.learning.cache.service.impl;
                                                                              import com.learning.cache.dao.StudentDao;
                                                                              import com.learning.cache.entity.Student;
                                                                              import com.learning.cache.service.StudentService;
                                                                              import org.springframework.beans.factory.annotation.Autowired;
                                                                              import org.springframework.cache.annotation.Cacheable;
                                                                              import org.springframework.stereotype.Service;
                                                                              import java.util.List;
                                                                              /**
                                                                               * @Description 学生服务实现类
                                                                               */
                                                                              @Service
                                                                              public class StudentServiceImpl implements StudentService {
                                                                                  @Autowired
                                                                                  private StudentDao studentDao;
                                                                                  @Cacheable(value={"com:learning:cache:list"})
                                                                                  @Override
                                                                                  public List list() {
                                                                                      return studentDao.selectList(null);
                                                                                  }
                                                                              }
                                                                              
                                                                              2.3.2 方法没有参数截图

                                                                              【springboot】缓存之@Cacheable、@CachePut、@CacheEvict的用法,在这里插入图片描述,第3张

                                                                              2.3.3 方法有一个参数示例
                                                                              package com.learning.cache.service.impl;
                                                                              import com.learning.cache.dao.StudentDao;
                                                                              import com.learning.cache.entity.Student;
                                                                              import com.learning.cache.service.StudentService;
                                                                              import org.springframework.beans.factory.annotation.Autowired;
                                                                              import org.springframework.cache.annotation.Cacheable;
                                                                              import org.springframework.stereotype.Service;
                                                                              import java.util.List;
                                                                              /**
                                                                               * @Description 学生服务实现类
                                                                               */
                                                                              @Service
                                                                              public class StudentServiceImpl implements StudentService {
                                                                                  @Autowired
                                                                                  private StudentDao studentDao;
                                                                                  // String id 一个参数的key情况
                                                                                  @Cacheable(value={"com:learning:cache:one"})
                                                                                  @Override
                                                                                  public Student getById(String id) {
                                                                                      return studentDao.selectById(id);
                                                                                  }
                                                                              }
                                                                              
                                                                              2.3.4 方法有一个参数截图

                                                                              【springboot】缓存之@Cacheable、@CachePut、@CacheEvict的用法,在这里插入图片描述,第4张

                                                                              2.3.5 方法有多个参数示例
                                                                              package com.learning.cache.service.impl;
                                                                              import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
                                                                              import com.learning.cache.dao.StudentDao;
                                                                              import com.learning.cache.entity.Student;
                                                                              import com.learning.cache.service.StudentService;
                                                                              import org.springframework.beans.factory.annotation.Autowired;
                                                                              import org.springframework.cache.annotation.Cacheable;
                                                                              import org.springframework.stereotype.Service;
                                                                              import java.util.List;
                                                                              /**
                                                                               * @Description 学生服务实现类
                                                                               */
                                                                              @Service
                                                                              public class StudentServiceImpl implements StudentService {
                                                                                  @Autowired
                                                                                  private StudentDao studentDao;
                                                                                  @Cacheable(value={"com:learning:cache:more"})
                                                                                  @Override
                                                                                  public Page page(int size, int current) {
                                                                                      Page page = new Page<>();
                                                                                      page.setCurrent(current);
                                                                                      page.setSize(size);
                                                                                      return studentDao.selectPage(page, null);
                                                                                  }
                                                                              }
                                                                              
                                                                              2.3.6 方法有多个参数截图

                                                                              【springboot】缓存之@Cacheable、@CachePut、@CacheEvict的用法,在这里插入图片描述,第5张

                                                                              2.3.7 指定key(从参数中指定)
                                                                              package com.learning.cache.service.impl;
                                                                              import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
                                                                              import com.learning.cache.dao.StudentDao;
                                                                              import com.learning.cache.entity.Student;
                                                                              import com.learning.cache.service.StudentService;
                                                                              import org.springframework.beans.factory.annotation.Autowired;
                                                                              import org.springframework.cache.annotation.Cacheable;
                                                                              import org.springframework.stereotype.Service;
                                                                              import java.util.List;
                                                                              /**
                                                                               * @Description 学生服务实现类
                                                                               */
                                                                              @Service
                                                                              public class StudentServiceImpl implements StudentService {
                                                                                  @Autowired
                                                                                  private StudentDao studentDao;
                                                                                  @Cacheable(value="com:learning:cache:one", key="#id")
                                                                                  @Override
                                                                                  public Student getById(String id) {
                                                                                      return studentDao.selectById(id);
                                                                                  }
                                                                              }
                                                                              
                                                                              2.3.8 指定key截图

                                                                              【springboot】缓存之@Cacheable、@CachePut、@CacheEvict的用法,在这里插入图片描述,第6张

                                                                              2.4 keyGenerator属性
                                                                              2.4.1 自定义key生成器代码示例
                                                                              package com.learning.cache.service.impl;
                                                                              import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
                                                                              import com.learning.cache.dao.StudentDao;
                                                                              import com.learning.cache.entity.Student;
                                                                              import com.learning.cache.service.StudentService;
                                                                              import org.springframework.beans.factory.annotation.Autowired;
                                                                              import org.springframework.cache.annotation.Cacheable;
                                                                              import org.springframework.stereotype.Service;
                                                                              import java.util.List;
                                                                              /**
                                                                               * @Description 学生服务实现类
                                                                               */
                                                                              @Service
                                                                              public class StudentServiceImpl implements StudentService {
                                                                                  @Autowired
                                                                                  private StudentDao studentDao;
                                                                                  @Cacheable(value="com:learning:cache:one", keyGenerator="customKeyGenerator")
                                                                                  @Override
                                                                                  public Student getById(String id) {
                                                                                      return studentDao.selectById(id);
                                                                                  }  
                                                                              }
                                                                              
                                                                              package com.learning.cache.config;
                                                                              import org.apache.ibatis.executor.Executor;
                                                                              import org.apache.ibatis.mapping.MappedStatement;
                                                                              import org.springframework.cache.interceptor.KeyGenerator;
                                                                              import org.springframework.context.annotation.Bean;
                                                                              import org.springframework.context.annotation.Configuration;
                                                                              import java.lang.reflect.Method;
                                                                              import java.sql.Statement;
                                                                              import java.util.Arrays;
                                                                              import java.util.UUID;
                                                                              /**
                                                                               * @Description 自定义Key生成器
                                                                               */
                                                                              @Configuration
                                                                              public class KeyGeneratorConfig {
                                                                                  @Bean("customKeyGenerator")
                                                                                  public KeyGenerator keyGenerator(){
                                                                                      return new KeyGenerator() {
                                                                                          @Override
                                                                                          public Object generate(Object o, Method method, Object... objects) {
                                                                                              return method.getName() + Arrays.asList(objects).toString() + UUID.randomUUID();
                                                                                          }
                                                                                      };
                                                                                  }
                                                                              }
                                                                              
                                                                              2.4.2 自定义key生成器截图

                                                                              【springboot】缓存之@Cacheable、@CachePut、@CacheEvict的用法,在这里插入图片描述,第7张

                                                                              2.5 cacheResolver属性
                                                                              2.5.1 自定义cacheResolver缓存解析器代码示例
                                                                              package com.learning.cache.service.impl;
                                                                              import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
                                                                              import com.learning.cache.dao.StudentDao;
                                                                              import com.learning.cache.entity.Student;
                                                                              import com.learning.cache.service.StudentService;
                                                                              import org.springframework.beans.factory.annotation.Autowired;
                                                                              import org.springframework.cache.annotation.Cacheable;
                                                                              import org.springframework.stereotype.Service;
                                                                              import java.util.List;
                                                                              /**
                                                                               * @Description 学生服务实现类
                                                                               */
                                                                              @Service
                                                                              public class StudentServiceImpl implements StudentService {
                                                                                  @Autowired
                                                                                  private StudentDao studentDao;
                                                                                  @Cacheable(value="com:learning:cache:one",key="#id", cacheResolver="customCacheResolver")
                                                                                  @Override
                                                                                  public Student getById(String id) {
                                                                                      return studentDao.selectById(id);
                                                                                  }
                                                                              }
                                                                              
                                                                              package com.learning.cache.resolver;
                                                                              import lombok.extern.slf4j.Slf4j;
                                                                              import org.springframework.cache.Cache;
                                                                              import org.springframework.cache.CacheManager;
                                                                              import org.springframework.cache.interceptor.*;
                                                                              import org.springframework.context.expression.MethodBasedEvaluationContext;
                                                                              import org.springframework.core.DefaultParameterNameDiscoverer;
                                                                              import org.springframework.core.ParameterNameDiscoverer;
                                                                              import org.springframework.expression.EvaluationContext;
                                                                              import org.springframework.expression.Expression;
                                                                              import org.springframework.expression.spel.standard.SpelExpressionParser;
                                                                              import java.lang.reflect.Method;
                                                                              import java.util.Collection;
                                                                              /**
                                                                               * @Description 自定义缓存解析器
                                                                               */
                                                                              @Slf4j
                                                                              public class CustomCacheResolver extends SimpleCacheResolver {
                                                                                  public CustomCacheResolver(CacheManager cacheManager) {
                                                                                      super(cacheManager);
                                                                                  }
                                                                                  @Override
                                                                                  public Collection resolveCaches(CacheOperationInvocationContext context) {
                                                                                      // 拿到缓存
                                                                                      Collection caches = super.resolveCaches(context);
                                                                                      Object target = context.getTarget();
                                                                                      BasicOperation operation = context.getOperation();
                                                                                      Method method = context.getMethod();
                                                                                      Object[] args = context.getArgs();
                                                                                      ParameterNameDiscoverer paramNameDiscoverer = new DefaultParameterNameDiscoverer();
                                                                                      EvaluationContext evaluationContext = new MethodBasedEvaluationContext(context.getOperation(), context.getMethod(), context.getArgs(), paramNameDiscoverer);
                                                                                      Expression expression = (new SpelExpressionParser()).parseExpression(((CacheableOperation) context.getOperation()).getKey());
                                                                                      // 获取所有的缓存的名字
                                                                                      context.getOperation().getCacheNames().forEach(cacheName -> {
                                                                                          log.info("缓存的name:{}", cacheName);
                                                                                          String key = cacheName + ':' + expression.getValue(evaluationContext, String.class);
                                                                                          log.info("缓存的key全路径:{}", key);
                                                                                      });
                                                                                      // 返回缓存
                                                                                      return caches;
                                                                                  }
                                                                              }
                                                                              
                                                                              2.5.2 自定义cacheResolver缓存解析器截图

                                                                              【springboot】缓存之@Cacheable、@CachePut、@CacheEvict的用法,在这里插入图片描述,第8张

                                                                              【springboot】缓存之@Cacheable、@CachePut、@CacheEvict的用法,在这里插入图片描述,第9张

                                                                              2.6 condition属性
                                                                              2.6.1 指定条件进行缓存代码示例
                                                                              package com.learning.cache.service.impl;
                                                                              import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
                                                                              import com.learning.cache.dao.StudentDao;
                                                                              import com.learning.cache.entity.Student;
                                                                              import com.learning.cache.service.StudentService;
                                                                              import org.springframework.beans.factory.annotation.Autowired;
                                                                              import org.springframework.cache.annotation.Cacheable;
                                                                              import org.springframework.stereotype.Service;
                                                                              import java.util.List;
                                                                              /**
                                                                               * @Description 学生服务实现类
                                                                               */
                                                                              @Service
                                                                              public class StudentServiceImpl implements StudentService {
                                                                                  @Autowired
                                                                                  private StudentDao studentDao;
                                                                              	// 指定id为1的可以缓存
                                                                                  @Cacheable(value="com:learning:cache:one", condition = "#id eq '1'")
                                                                                  @Override
                                                                                  public Student getById(String id) {
                                                                                      return studentDao.selectById(id);
                                                                                  }
                                                                              }
                                                                              
                                                                              2.6.2 指定条件进行缓存截图

                                                                              【springboot】缓存之@Cacheable、@CachePut、@CacheEvict的用法,在这里插入图片描述,第10张

                                                                              【springboot】缓存之@Cacheable、@CachePut、@CacheEvict的用法,在这里插入图片描述,第11张

                                                                              2.7 unless属性
                                                                              2.7.1 指定条件不进行缓存代码示例
                                                                              package com.learning.cache.service.impl;
                                                                              import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
                                                                              import com.learning.cache.dao.StudentDao;
                                                                              import com.learning.cache.entity.Student;
                                                                              import com.learning.cache.service.StudentService;
                                                                              import org.springframework.beans.factory.annotation.Autowired;
                                                                              import org.springframework.cache.annotation.Cacheable;
                                                                              import org.springframework.stereotype.Service;
                                                                              import java.util.List;
                                                                              /**
                                                                               * @Description 学生服务实现类
                                                                               */
                                                                              @Service
                                                                              public class StudentServiceImpl implements StudentService {
                                                                                  @Autowired
                                                                                  private StudentDao studentDao;
                                                                              	// 对查询结果为null的不做缓存,去掉的话会缓存空值
                                                                                  @Cacheable(value="com:learning:cache:one", unless = "#result == null")
                                                                                  @Override
                                                                                  public Student getById(String id) {
                                                                                      return studentDao.selectById(id);
                                                                                  }
                                                                              }
                                                                              
                                                                              2.7.2 结果为null的缓存截图

                                                                              【springboot】缓存之@Cacheable、@CachePut、@CacheEvict的用法,在这里插入图片描述,第12张

                                                                              2.8 allEntries属性
                                                                              2.8.1 清除全部缓存代码示例
                                                                              package com.learning.cache.service.impl;
                                                                              import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
                                                                              import com.learning.cache.dao.StudentDao;
                                                                              import com.learning.cache.entity.Student;
                                                                              import com.learning.cache.service.StudentService;
                                                                              import org.springframework.beans.factory.annotation.Autowired;
                                                                              import org.springframework.cache.annotation.CacheEvict;
                                                                              import org.springframework.cache.annotation.Cacheable;
                                                                              import org.springframework.stereotype.Service;
                                                                              import java.util.List;
                                                                              /**
                                                                               * @Description 学生服务实现类
                                                                               */
                                                                              @Service
                                                                              public class StudentServiceImpl implements StudentService {
                                                                                  @Autowired
                                                                                  private StudentDao studentDao;
                                                                                  
                                                                                  @Cacheable(value="com:learning:cache:one")
                                                                                  @Override
                                                                                  public Student getById(String id) {
                                                                                      return studentDao.selectById(id);
                                                                                  }
                                                                                  @CacheEvict(value="com:learning:cache:one", allEntries = true)
                                                                                  @Override
                                                                                  public boolean delete(String id) {
                                                                                      int result = studentDao.deleteById(id);
                                                                                      if(result > 0){
                                                                                          return true;
                                                                                      }
                                                                                      return false;
                                                                                  }
                                                                              }
                                                                              
                                                                              2.8.2 先查2次缓存起来,然后删除1条,清除所有截图

                                                                              【springboot】缓存之@Cacheable、@CachePut、@CacheEvict的用法,在这里插入图片描述,第13张

                                                                              【springboot】缓存之@Cacheable、@CachePut、@CacheEvict的用法,在这里插入图片描述,第14张

                                                                              【springboot】缓存之@Cacheable、@CachePut、@CacheEvict的用法,在这里插入图片描述,第15张

                                                                              【springboot】缓存之@Cacheable、@CachePut、@CacheEvict的用法,在这里插入图片描述,第16张

                                                                              【springboot】缓存之@Cacheable、@CachePut、@CacheEvict的用法,在这里插入图片描述,第17张

                                                                              三、注意事项
                                                                              • 1.@CacheEvict注解测试的时候尽量调接口测试,不要用页面去触发,例如修改某条数据,清除分页数据缓存,修改完成后页面有可能会再次调用分页接口,导致分页的@Cableable仍然缓存,造成@CacheEvict失效的假象