使用@Cacheable,缓存优化的方式优化数据库的查询

小灰灰 2024-03-16 13:46 76阅读 0赞

使用@Cacheable,缓存优化的方式优化数据库的查询

本文讲解在springboot中如何利用@Cacheable,通过添加本地缓存,来优化查询,提升查询效率。

简介

在实际业务中,如果某些数据被频繁访问,则每次都去读取数据库显然是不太优雅的。此时,我们可以添加本地缓存来提高系统的查询效率。在Java中,我们可以使用基于ConcurrentHashMap等数据结构实现的Local Cache,在内存层面对数据进行缓存,从而避免频繁访问数据库。

例如,在图书管理系统中,我们可以添加一个名为bookCache的ConcurrentHashMap缓存对象,用于存储Book类的对象。当我们进行查询操作时,先在缓存对象中寻找是否存在所需的Book对象,如果已经存在则直接返回;否则再从数据库中读取,并将其缓存至bookCache中,从而加快下一次查询的速度。

@Cacheable简介

首先,我们需要引入Spring Boot自带的缓存模块,可以在pom.xml文件中添加如下依赖:

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-cache</artifactId>
  4. </dependency>

接下来,在我们的Service层中,我们可以使用Mybatis-Plus提供的IService接口作为基础Service,然后使用Spring Boot的@Cacheable注解为其添加缓存功能。例如,我们可以在Service接口方法上添加如下代码:

  1. @Override
  2. @Cacheable(value = "book", key = "#isbn")
  3. public Book getByIsbn(String isbn) {
  4. // 从数据库中读取图书信息并返回
  5. }

其中,@Cacheable注解表示启用缓存,并指定value参数为book,表示缓存Key; key参数为#isbn,则表示缓存的键名为isbn变量的值。

此外,在使用@Cacheable注解前,我们还需要增加@EnableCaching注解激活缓存。例如,在Spring Boot项目启动类中,我们可以添加如下代码:

  1. @SpringBootApplication
  2. @EnableCaching
  3. public class Application {
  4. public static void main(String[] args) {
  5. SpringApplication.run(Application.class, args);
  6. }
  7. }

这样,当我们调用Service层的getByIsbn方法时,Spring就会自动从本地缓存中获取相应的数据。如果缓存中不存在相应的数据,则再从数据库中读取,并将其缓存到本地。

需要注意的是,当使用缓存时,我们需要适度控制缓存时间和尺寸,以避免过期或者内存溢出等问题。此外,在分布式环境下,我们还需要设计好缓存的更新与同步机制,保证数据的一致性和正确性。

同时,我们也可以在类上方添加@CacheConfig注解,统一配置缓存,例如:

  1. @Service
  2. @CacheConfig(cacheNames = "bookCache")
  3. public class BookServiceImpl extends ServiceImpl<BookMapper, Book> implements IBookService {
  4. @Override
  5. @Cacheable(key = "#isbn")
  6. public Book selectByIsbn(String isbn) {
  7. // ...
  8. }
  9. }

这样,我们就能够在Spring Boot + Mybatis-Plus + Lombok的架构中为Service层添加本地缓存的功能了。在读取数据较为频繁,但数据更新较少的情况下,使用本地缓存可以大幅提高程序的效率和响应速度。

代码注意事项

首先,需要添加如下依赖,包括Spring Boot、Mybatis-Plus、Lombok和Caffeine缓存模块:

  1. <!-- Spring Boot -->
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-web</artifactId>
  5. </dependency>
  6. <!-- Mybatis-Plus -->
  7. <dependency>
  8. <groupId>com.baomidou</groupId>
  9. <artifactId>mybatis-plus-boot-starter</artifactId>
  10. <version>3.4.1</version>
  11. </dependency>
  12. <!-- Lombok -->
  13. <dependency>
  14. <groupId>org.projectlombok</groupId>
  15. <artifactId>lombok</artifactId>
  16. <optional>true</optional>
  17. </dependency>
  18. <!-- Caffeine -->
  19. <dependency>
  20. <groupId>com.github.ben-manes.caffeine</groupId>
  21. <artifactId>caffeine</artifactId>
  22. <version>3.0.6</version>
  23. </dependency>

接下来,我们创建一个基于Mybatis-Plus提供的IService接口的Service类,并使用@Cacheable注解为其中的方法添加缓存功能。例如:

  1. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  2. import org.springframework.cache.annotation.CacheEvict;
  3. import org.springframework.cache.annotation.Cacheable;
  4. import org.springframework.stereotype.Service;
  5. @Service
  6. public class BookServiceImpl extends ServiceImpl<BookMapper, Book> implements IBookService {
  7. @Override
  8. @Cacheable(value = "book", key = "#isbn")
  9. public Book getByIsbn(String isbn) {
  10. QueryWrapper<Book> queryWrapper = new QueryWrapper<>();
  11. queryWrapper.eq("isbn", isbn);
  12. return baseMapper.selectOne(queryWrapper);
  13. }
  14. @Override
  15. @CacheEvict(value = "book", key = "#isbn")
  16. public void deleteByIsbn(String isbn) {
  17. QueryWrapper<Book> queryWrapper = new QueryWrapper<>();
  18. queryWrapper.eq("isbn", isbn);
  19. baseMapper.delete(queryWrapper);
  20. }
  21. }

在上述代码中,@Cacheable注解用于缓存getByIsbn方法的返回值;value参数为book,表示缓存Key;key参数为#isbn,则表示缓存的键名为传入的isbn值。

同时,我们还为删除ISBN记录(deleteByIsbn方法)增加了@CacheEvict注解,表示当该方法执行时,会清除与isbn对应的本地缓存。这样,当我们执行删除操作后,就不会出现脏数据。

另外,在Spring Boot启动类中我们需要使用@EnableCaching注解激活缓存:

  1. @SpringBootApplication
  2. @EnableCaching
  3. public class Application {
  4. // ...
  5. }

最后,在application.yml配置文件中添加以下内容,指定采用Caffeine作为本地缓存:

  1. spring:
  2. cache:
  3. type: caffeine
  4. caffeine:
  5. spec: maximumSize=100,expireAfterAccess=10s

这里我们指定本地缓存最大数量为100,过期时间为10秒。

发表评论

表情:
评论列表 (有 0 条评论,76人围观)

还没有评论,来说两句吧...

相关阅读

    相关 数据库性能优化缓存优化

    数据库性能优化中的缓存优化 在大型应用程序中,数据库的性能优化是非常重要的,因为数据库往往是应用程序的瓶颈。数据库的性能优化可以从多个方面入手,其中一个重要的方面就是缓存

    相关 数据库优化-缓存穿透

    缓存穿透是指客户端请求的数据在缓存和数据库中都不存在,这样缓存永远不会生效,这些请求都会打到数据库。常见的解决方案有两种。 1、缓存空对象 例如用户携带id请求后端,但

    相关 数据库 查询优化

    避免全表扫描 当我们的where过滤的字段没有索引时,就会发生全表扫描,如下,当我们的Name字段没有索引时,就会发生全部扫描 select fro

    相关 mysql数据库查询优化-缓存

    查询执行的基础 一.基础 当希望mysql能够以更高的性能运行查询时,最好的办法就是弄清楚mysql是如何优化和执行查询的,基本可以从以下3点开始了解: 1.客户端