實現SpringBoot + Redis快取的原始碼與教程

banq發表於2021-08-06

總結了Redis的基礎知識以及如何使用Redis在Spring Boot中整合快取。
 
首先是依賴:

<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>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <scope>runtime</scope>
</dependency>

使用MySQL作為我的主要資料庫,所以我使用 MySQL 聯結器,還有 Spring Data Redis (access+driver) 依賴項在我們的專案中用作 Java Redis 客戶端,這允許我們的應用程式啟用 Redis 快取機制。
現快取時常用的註解如下:@CachePut、@CacheEvict、@Cacheable、@Caching,我們將看到我們在哪裡以及如何使用這些註解。

@Entity
public class User implements Serializable{
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;
    private String name;
    private String email;
    private Integer age;
    public User() {
        super();
    }
    
    public User(Integer id, String name, String email, Integer age) {
        super();
        this.id = id;
        this.name = name;
        this.email = email;
        this.age = age;
    }


 

啟用

@SpringBootApplication
@EnableCaching
public class RedisCacheApplication {

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

只要透過@EnableCaching註釋啟用快取支援,Spring Boot 就會自動配置快取基礎結構。
 

查詢
在控制器中,我們必須在每個 API 之上新增不同的註釋來快取特定記錄。

@GetMapping("/{id}")
@Cacheable(value= "Users", key="id")
public User getUser(@PathVariable Integer id) {
    log.info(">> User Controller: get user by id: " + id);
    return userService.getUserById(id);
}


在 GET 方法之上,我們使用@Cacheablewhich 表示每次呼叫該方法時,都會應用快取行為,檢查是否已經為給定的引數呼叫了該方法。
value="{category}"指定資料需要儲存在哪個類別下。對於不同的控制器,我們可以使用不同的值。
一個合理的預設值只是使用方法引數來計算鍵,但我們也可以指定鍵以及使用key="#{value}"哪個將用於識別特定記錄。
如果在快取中找不到計算鍵或指定鍵的值,則將呼叫目標方法並將返回值儲存在關聯的快取中。返回型別會自動處理,如果存在,它們的內容儲存在快取中。
 

儲存

@PutMapping
@CachePut(value="users", key="user", unless="result == null")
public User updateUser(@RequestBody User user) {
log.info(">> User Controller: update user: " + user.toString());
return userService.update(user);
}

在PUT 方法之上,我們使用@CachePut. 我們也可以使用@CachePut本身來儲存新使用者,即POST 方法。
如果condition() 和unless() 表示式相應地匹配,則它始終會導致呼叫該方法並將其結果儲存在關聯的快取中。Condition() 是 Spring 表示式語言 (SpEL) 表示式,用於有條件地進行快取放置操作。由於 put 操作的性質,該表示式在呼叫方法後計算,因此可以引用方法的呼叫結果。
 

刪除

@DeleteMapping("/{id}")
@CacheEvict(value= "Users", allEntries = false, key="id")
public void removeUser(@PathVariable Integer id) {
  log.info(">> User Controller: delete user: " + id);
  userService.delete(id);
}


在 DELETE 方法之上,我們使用@CacheEvict它允許我們刪除 Redis 中特定鍵的資料。allEntries指定是否應刪除快取中的所有條目。預設情況下,僅刪除關聯鍵下的值。請注意,不允許將此引數設定為 true 並指定鍵。
 

應用程式屬性
我們可以透過不同的屬性在我們的應用程式中配置 Redis 快取,我使用了以下屬性,如下所示:

spring.redis.host=localhost
spring.redis.port=6379
spring.cache.redis.time-to-live=60000
spring.cache.cache-names=users,product,order


預設情況下,會根據需要建立快取,但您可以透過設定該cache-names屬性來限制可用快取的列表。
我們可以用來在Spring中配置 Redis 快取的屬性如下所示:

要記住的要點
  • 定義 TTLs :生存時間 (TTL),是您的快取將刪除條目的時間跨度。如果您只想每分鐘獲取一次資料,只需使用 @Cacheable Annotation 保護它並將 TTL 設定為 1 分鐘。
  • 實現 Serializable:如果你在 Redis 快取中新增一個物件,那麼該物件應該實現一個 Serializable 介面。
  • Redis 快取限制:當快取大小達到記憶體限制時,舊資料將被刪除,為新資料騰出空間。儘管 Redis 速度非常快,但在 64 位系統上儲存任何數量的資料仍然沒有限制。它只能在 32 位系統上儲存 3GB 的資料。
  • 永遠不要從同一個類中呼叫可快取方法:原因是 Spring 代理了對這些方法的訪問,以使快取抽象工作。當你在同一個類中呼叫它時,這個代理機制不會啟動。透過這個,你基本上繞過了你的快取並使其無效。


原始碼:https://github.com/Vinesh-z/Redis-Caching-Example
 

相關文章