Spring Boot Redis 缓存

Spring Boot Redis 缓存

spring boot redis cache

Spring Boot Redis 项目设置

spring boot redis cache example

Spring Boot Redis 缓存 Maven 依赖

尽管我们已经使用工具完成了设置,但如果你想手动进行设置,我们在这个项目中使用Maven构建系统,以下是我们使用的依赖项。

<parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>1.5.9.RELEASE</version>
  <relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  <java.version>1.8</java.version>
</properties>
<dependencies>
  <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-data-redis</artifactId>
  </dependency>

  <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-web</artifactId>
  </dependency>

  <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-test</artifactId>
     <scope>test</scope>
  </dependency>

  <!-- for JPA support -->
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
  </dependency>

  <!-- for embedded database support -->
  <dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <scope>runtime</scope>
  </dependency>

</dependencies>

<build>
  <plugins>
     <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
     </plugin>
  </plugins>
</build>

确保使用来自Maven中央仓库的稳定版本的Spring Boot。

定义模型

为了将一个对象保存到Redis数据库中,我们定义一个包含基本字段的Person模型对象。

package com.Olivia.rediscachedemo;

import javax.persistence.*;
import java.io.Serializable;

@Entity
public class User implements Serializable {

    private static final long serialVersionUID = 7156526077883281623L;

    @Id
    @SequenceGenerator(name = "SEQ_GEN", sequenceName = "SEQ_USER", allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_GEN")
    private Long id;
    private String name;
    private long followers;

    public User() {
    }

    public User(String name, long followers) {
        this.name = name;
        this.followers = followers;
    }

    //standard getters and setters

    @Override
    public String toString() {
        return String.format("User{id=%d, name='%s', followers=%d}", id, name, followers);
    }
}

这是一个具备getter和setter方法的标准POJO。

配置 Redis 缓存

使用Spring Boot和已經在Maven中安裝的必要依賴,我們只需要在application.properties文件中添加三行代碼,就可以配置本地的Redis實例。

# Redis Config
spring.cache.type=redis
spring.redis.host=localhost
spring.redis.port=6379

还有,在Spring Boot主类上使用@EnableCaching注解。

package com.Olivia.rediscachedemo;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;

@SpringBootApplication
@EnableCaching
public class Application implements CommandLineRunner {

  private final Logger LOG = LoggerFactory.getLogger(getClass());
  private final UserRepository userRepository;

  @Autowired
  public Application(UserRepository userRepository) {
    this.userRepository = userRepository;
  }

  public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
  }

  @Override
  public void run(String... strings) {
    //Populating embedded database here
    LOG.info("Saving users. Current user count is {}.", userRepository.count());
    User shubham = new User("Shubham", 2000);
    User Olivia = new User("Pankaj", 29000);
    User lewis = new User("Lewis", 550);

    userRepository.save(shubham);
    userRepository.save(Olivia);
    userRepository.save(lewis);
    LOG.info("Done saving users. Data: {}.", userRepository.findAll());
  }
}

我们添加了一个CommandLineRunner,因为我们想在嵌入式H2数据库中填充一些样本数据。

定义储存库

在展示Redis的工作方式之前,我们将先定义一个与JPA相关功能有关的存储库。

package com.Olivia.rediscachedemo;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface UserRepository extends JpaRepository { }

目前它没有任何方法调用,因为我们并不需要。

定义控制器

控制器是调用Redis缓存进行操作的位置。实际上,这是最好的地方,因为缓存与控制器直接关联,请求甚至不需要进入服务代码等待缓存结果。以下是控制器的框架:

package com.Olivia.rediscachedemo;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.*;

@RestController
public class UserController {

  private final Logger LOG = LoggerFactory.getLogger(getClass());

  private final UserRepository userRepository;

  @Autowired
  public UserController(UserRepository userRepository) {
    this.userRepository = userRepository;
  }
   ...
}

现在,要将某物放入缓存中,我们使用@Cacheable注解。

@Cacheable(value = "users", key = "#userId", unless = "#result.followers < 12000")
@RequestMapping(value = "/{userId}", method = RequestMethod.GET)
public User getUser(@PathVariable String userId) {
  LOG.info("Getting user with ID {}.", userId);
  return userRepository.findOne(Long.valueOf(userId));
}

在上述映射中,getUser方法将一个人放入名为’users’的缓存中,通过键值’userId’来标识该人,并且只会存储关注者数量大于12000的用户。这确保了缓存中只有非常受欢迎且经常被查询的用户。此外,我们在API调用中故意添加了一个日志记录语句。让我们此刻通过Postman进行一些API调用。以下是我们所进行的调用:

localhost:8090/1
localhost:8090/1
localhost:8090/2
localhost:8090/2

如果我们注意日志,这些就是它们。

... : Getting user with ID 1.
... : Getting user with ID 1.
... : Getting user with ID 2.

注意到什么了吗?我们进行了四次API调用,但只有三个日志语句。这是因为用户ID为2的用户拥有29000个关注者,所以它的数据被缓存了起来。这意味着当进行API调用时,数据将从缓存中返回,而不需要从数据库中获取!

更新缓存

当实际对象的值更新时,缓存值也应该更新。可以使用@CachePut注解来实现这一点。

@CachePut(value = "users", key = "#user.id")
@PutMapping("/update")
public User updatePersonByID(@RequestBody User user) {
  userRepository.save(user);
  return user;
}

通过这个方法,一个人的身份再次通过身份证进行识别,并且更新该人的结果。

清除缓存

如果要从实际数据库中删除某些数据,那么在缓存中保留它就没有意义了。我们可以使用@CacheEvict注解清除缓存数据。

@CacheEvict(value = "users", allEntries=true)
@DeleteMapping("/{id}")
public void deleteUserByID(@PathVariable Long id) {
  LOG.info("deleting person with id {}", id);
  userRepository.delete(id);
}

在上一次映射中,我们只是清除了缓存条目,没有做其他任何操作。

运行Spring Boot Redis缓存应用程序

我们可以通过使用一个简单的命令来运行这个应用程序。

mvn spring-boot:run

Redis 缓存的限制

虽然Redis非常快,但在64位系统上存储任意数量的数据仍然没有限制。在32位系统上,它只能存储3GB的数据。可用内存越多,命中率就越高,但是一旦Redis占用了过多的内存,这种趋势就会停止。当缓存大小达到内存限制时,旧数据会被删除以给新数据腾出位置。

请用中文进行本地化的改写:
总结

在这节课中,我们学习了Redis缓存提供的快速数据交互功能,以及如何在Spring Boot中进行最小且强大的配置来集成它。欢迎在下方留下评论。

发表回复 0

Your email address will not be published. Required fields are marked *