Springboot缓存的使用1

什么是缓存

缓存是为了解决CPU速度和内存速度的速度差异问题。内存中被CPU访问最频繁的数据和指令被复制入CPU中的缓存,这样CPU就可以不经常到象“蜗牛”一样慢的内存中去取数据了,CPU只要到缓存中去取就行了,而缓存的速度要比内存快很多。

spring缓存是什么

反正也就一个道理,存储一些我们经常要用的的数据
减轻数据库的压力

spring中缓存的注解

@EnableCaching

  1. 是什么
    开启基于注解的缓存
  2. 怎么用
    标注在方法类中
@EnableCaching//开启缓存注解
public class BookService {
}

@Cacheable

  1. 是什么
    当第一次访问的时候,把结果返回给用户,并把结果数据存到缓存中,下次访问不经过方法,直接返回缓存中的数据,一般用作查找
  2. 参数有什么
key作用
cacheNames/value表示缓存组件的名字
key/keyGenerator表示存储到缓存的键名,可以用spel表达式/key的生成策略
cacheManager/cacheResolver指定用什么做管理器,管理多个组件,比如用redis的缓存,或者自带的默认的concurrenthashmap
condition条件成功缓存,可以用spel表达式
unless条件成功不缓存,可以用spel表达式

3,举例子
实体类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Book {
    Long bookId;
    String bookName;
}

service层(用静态代码块不连接数据库了 方便一点。。。)

@Component
@EnableCaching//开启缓存注解
public class BookService {


    public static HashMap<Long, Book> map = new HashMap<>();
    static {
        map.put(1L,new Book(1L,"老人与海"));
        map.put(2L,new Book(2L,"海的女儿"));
        map.put(3L,new Book(3L,"红高粱"));
    }
    @Cacheable(value = "book",key = "#id")
    public Book getBookById(Long id){
        Book book = map.get(id);
        System.out.println(book);
        return map.get(id);
    }
}

控制层

@RestController
public class BookController {

    @Autowired
    BookService bookService;
    @GetMapping("/get")
    public Book getByBookId(Long id){
        return bookService.getBookById(id);
    }
}

开机启动
第一次访问
在这里插入图片描述
清空控制台第二次访问
在这里插入图片描述
没有任何打印,说明缓存成功了?
那么它存储到哪里去了
经过调试
在CacheConfigurations中有这么一段代码存放着缓存配置

static {
        Map<CacheType, Class<?>> mappings = new EnumMap(CacheType.class);
        mappings.put(CacheType.GENERIC, GenericCacheConfiguration.class);
        mappings.put(CacheType.EHCACHE, EhCacheCacheConfiguration.class);
        mappings.put(CacheType.HAZELCAST, HazelcastCacheConfiguration.class);
        mappings.put(CacheType.INFINISPAN, InfinispanCacheConfiguration.class);
        mappings.put(CacheType.JCACHE, JCacheCacheConfiguration.class);
        mappings.put(CacheType.COUCHBASE, CouchbaseCacheConfiguration.class);
        mappings.put(CacheType.REDIS, RedisCacheConfiguration.class);
        mappings.put(CacheType.CAFFEINE, CaffeineCacheConfiguration.class);
        mappings.put(CacheType.SIMPLE, SimpleCacheConfiguration.class);
        mappings.put(CacheType.NONE, NoOpCacheConfiguration.class);
        MAPPINGS = Collections.unmodifiableMap(mappings);
    }

默认实现的就是
SimpleCacheConfiguration.class的配置
而这个配置类中有这么一段bean

	@Bean
    ConcurrentMapCacheManager cacheManager(CacheProperties cacheProperties, CacheManagerCustomizers cacheManagerCustomizers) {
        ConcurrentMapCacheManager cacheManager = new ConcurrentMapCacheManager();
        List<String> cacheNames = cacheProperties.getCacheNames();
        if (!cacheNames.isEmpty()) {
            cacheManager.setCacheNames(cacheNames);
        }

        return (ConcurrentMapCacheManager)cacheManagerCustomizers.customize(cacheManager);
    }

在点进去一看发现存储的就是用concurrenthasp
难怪我之前实习的时候项目经理说你用缓存干嘛不自己写一个hashmap!!!

@CachePut

  1. 是什么
    当第一次访问的时候,把结果返回给用户,并把结果数据存到缓存中,下次还访问方法,并重新设置缓存中的数据简单来说就是每次执行方法每次存数据!一般用作更新
  2. 注解参数
    同@CachePut一样
  3. 测试
    service
    @CachePut(value = "book",key = "#a0.bookId")//#a0代表参数中第一个参数的bookId作为key
    public Book updateBook(Book book){
        System.out.println("要修改的书本数据:"+book);
        map.put(book.getBookId(),book);
        return map.get(book.getBookId());
    }

控制层

    @GetMapping("/update")
    public Book updateBook(Book book){
        Book book1 = bookService.updateBook(book);
        return book1;
    }

开机启动
查询数据
在这里插入图片描述
更新数据
在这里插入图片描述
在查询一次数据
在这里插入图片描述
数据改了,而且没在访问查询的代码而是直接访问缓存了(注意,缓存的key一定要一样根据id来)

@CacheEvict

  1. 是什么
    根据key删除缓存一般用作删除
  2. 注解参数
    同@CachePut一样
    但是多了2个
key作用
allEntries是否需要清除管理器缓存中的所有元素默认为false
beforeInvocation是否在方法前删除缓存默认false
  1. 测试
    service
    @CacheEvict(value = "book",key = "#id")
    public void delete(Long id){
        System.out.println("删除缓存:"+id);
    }

控制层

    @GetMapping("/delete")
    public String deleteBook(Long id){
        bookService.delete(id);
        return "删除成功";
    }

启动
先查询id=1
在这里插入图片描述
这时候缓存了key=1的缓存,这时候我们删除缓存
在这里插入图片描述
我们在查询一下id=1
在这里插入图片描述
这时候发现缓存没了,执行方法里面
结束!
4. 测试(beforeInvocation)
service

    @CacheEvict(value = "book",key = "#id",beforeInvocation = true)
    public void delete(Long id){
        System.out.println("删除缓存:"+id);
        int a = 10/0;
        map.remove(id);
    }

控制层

    @GetMapping("/delete")
    public String deleteBook(Long id){
        bookService.delete(id);
        return "删除成功";
    }

启动
先查询id=1
在这里插入图片描述
删除
在这里插入图片描述
我故意写个异常在里面,看看方法执行前有没有删除缓存
在执行查询
在这里插入图片描述
有执行方法体的内容了,说明在执行删除前已经删除缓存了!
在缓存后删除可以自行测试
还有那个allEntries 也可以自行测试

@CacheConfig

  1. 是什么
    标注在类上,表面这个类所有方法的缓存的一些属性是都是这个
  2. 参数
key作用
cacheNames表示缓存组件的名字
keyGenerator表面key的生成策略
cacheManager/cacheResolver

总结

这可能只是基本的使用
后续当我们用redis等中间件做缓存
根据spring规则注入使用
切忌!缓存最好不要乱用!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值