当前位置: 首页>后端>正文

我的Spring boot的Demo3(Cache的使用 )

Spring boot 的cache相关介绍

随着时间的积累,应用的使用用户不断增加,数据规模也越来越大,往往数据库查询操作会成为影响用户使用体验的瓶颈,此时使用缓存往往是解决这一问题非常好的手段之一。

Spring 3开始提供了强大的基于注解的缓存支持,可以通过对方法进行注解来实现缓存功能,提高数据访问性能。Spring提供了各种xxxCache的实现;如RedisCache,EhCacheCache , ConcurrentMapCache。

核心思想:当我们在调用一个缓存方法时会把该方法参数和返回结果作为一个键值对存放在缓存中,等到下次利用同样的参数来调用该方法时将不再执行该方法,而是直接从缓存中获取结果进行返回。

EhCache 是?个?较成熟的 Java 缓存框架,最早从 hibernate 发展?来, 是进程中的缓存系统,它提供了?内存,磁盘?件存储,以及分布式存储?式等多种灵活的 cache 管理?案,快速简单。SpringCache 实现的EhCacheCache,就集成了 Ehcache。

Spring cache 相关注解说明

  1. @Cacheable
    用于读取数据的?法。每次调用该标注的方法时,Spring会先检查缓存中是否有过;如果有就直接从缓存中获结果,如果没有有再调?该?法获取数据,然后把数据添加到缓存中。

  2. @CachePut
    用于写数据的?法上,如新增/修改?法,调??法时会更新缓存数据 ,修改了数据库中的数据,同时又更新了缓存。结合@Cacheable一起使用才有意义。

  3. @CacheEvict
    ?于移除数据的?法上,如删除?法,调??法时会从缓存中移除相应的数据,结合@Cacheable一起使用才有意义。

  4. @Caching
    此注解用于复杂的缓存操作的方法上,可以对@Cacheable、@CachePut、@CacheEvict注解的进行组合。

  5. @CacheConfig
    ?于标注在类上,可以存放该类中所有缓存的公有属性,?如设置缓存的名字。可以抽取@Cacheable、@CachePut、@CacheEvict的公共属性值

使用Spring缓存抽象时我们需要关注以下两点:
1. 确定方法需要被缓存以及他们的缓存策略
2. 从缓存中读取之前缓存存储的数据

注意:不能在同一个类中调用被注解缓存了的方法,这样会导致缓存失效。

项目实例

此Demo3是在我之前的Demo2上进行修改得来的。

首先要在@SpringBootApplication进行@EnableCaching注解,来启用cache

@SpringBootApplication
@EnableCaching      // 开启缓存注解!
public class CachedemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(CachedemoApplication.class, args);
    }

}

然后在Service层进行缓存注释。写在Controller层也是可以生效的。

@Service
public class BookService {

    private BookRepository bookRepository =new BookRepository();

    /**1. @Cacheable的几个属性详解:
     *       cacheNames/value:指定缓存组件的名字
     *       key:缓存数据使用的key,可以用它来指定。默认使用方法参数的值,一般不需要指定
     *       keyGenerator:作用和key一样,二选一
     *       cacheManager和cacheResolver作用相同:指定缓存管理器,二选一
     *       condition:指定符合条件才缓存,比如:condition="#id>3"
     *                   也就是说传入的参数id>3才缓存数据
     *      unless:否定缓存,当unless为true时不缓存,可以获取方法结果进行判断
     *      sync:是否使用异步模式*/
    //@Cacheable(cacheNames= "book")
    //@Cacheable(cacheNames= "book",key="#id",condition="#id>3")

    @Cacheable(cacheNames = "book",key="#id")
    public Book queryBookById(int id){
        System.out.println("正在从数据库里面读取数据...");
        return bookRepository.queryBookById(id);
    }


    /**
     * @CachePut:即调用方法,又更新缓存数据
     * 修改了数据库中的数据,同时又更新了缓存
     *
     *运行时机:
     * 1.先调用目标方法
     * 2.将目标方法返回的结果缓存起来
     *
     * 这样写:@CachePut(cacheNames = "book",key = "#book.id")
     *         @CachePut(cacheNames = "book",key = "#result.id")
     */
    @CachePut(cacheNames = "book",key = "#result.id")
    public Book updateBook(Book book){
        System.out.println("修改"+book.getName()+"的书籍信息");
        bookRepository.updateBookByName(book.getName());
        return book;

    }


    /**
     * @CacheEvict:清除缓存
     *    1.key:指定要清除缓存中的某条数据
     *    2.allEntries=true:删除缓存中的所有数据
     *    beforeInvocation=false:默认是在方法之后执行清除缓存
     *    3.beforeInvocation=true:现在是在方法执行之前执行清除缓存,
     *                          作用是:只清除缓存、不删除数据库数据
     */
    //@CacheEvict(cacheNames = "book",key = "#id")
    @CacheEvict(cacheNames = "book",allEntries=true)
    public void deleteBook(Integer id){
        System.out.println("删除了书籍信息");
        //删除数据库数据的同时删除缓存数据
        bookRepository.deleteBookById(id);
        /**
         * beforeInvocation=true
         * 使用在方法之前执行的好处:
         * 1.如果方法出现异常,缓存依旧会被删除
         */
    }

    @Cacheable(cacheNames = "booklist")
    public List<Book> queryAllBook(){
        return bookRepository.queryAllBook();
    }

}

结果显示

我的Spring boot的Demo3(Cache的使用 ),第1张
读取第一本书

我的Spring boot的Demo3(Cache的使用 ),第2张
正常调用了方法
我的Spring boot的Demo3(Cache的使用 ),第3张
第二次读取

我的Spring boot的Demo3(Cache的使用 ),第4张
但读取方法并没有被调用,说明直接从缓存里面读取数据

参考链接

SpringBoot中Cache缓存的使用
https://blog.csdn.net/weixin_36279318/article/details/82820880

史上最全的Spring Boot Cache使用与整合
https://blog.csdn.net/qq_32448349/article/details/101696892

Restful接口开发(6):缓存服务Cache/Redis
https://blog.csdn.net/u010886217/article/details/102919253

https://www.bilibili.com/video/BV1rq4y1s7H2?p=25

https://www.xamrdz.com/backend/3fm1926801.html

相关文章: