1. 程式人生 > 實用技巧 >一篇文章帶你搞定 Spring Cache 整合 Redis

一篇文章帶你搞定 Spring Cache 整合 Redis

一、前期配置

首先W建一個 Springboot 工程,引入依賴:
Spring Web,Spring cache,redis,Spring Security


配置 application.properties

spring.redis.host=192.168.176.128
spring.redis.port=6379
#給快取取一個名字,後面會用到
spring.cache.cache-names=yolo
  • 1
  • 2
  • 3
  • 4

二、快取使用

(1)@CacheConfig

這個註解在類上使用,用來描述該類中所有方法使用的快取名稱,當然也可以不使用該註解,直接在具體的快取註解上配置名稱,示例程式碼如下:

@Service
@CacheConfig(cacheNames = "yolo")
public class UserService {
}
  • 1
  • 2
  • 3
  • 4

可以看到 快取的 key 會都加上該名字:

(2)@Cacheable

這個註解一般加在查詢方法上,表示將一個方法的返回值快取起來,預設情況下,快取的key就是方法的引數,快取的value就是方法的返回值。示例程式碼如下:

@Cacheable(key = "#id")
public User getUserById(Integer id,String username) {
    System.out.println("getUserById");
    return getUserFromDBById(id);
}
  • 1
  • 2
  • 3
  • 4
  • 5

當有多個引數時,預設就使用多個引數來做key,如果只需要其中某一個引數做key,則可以在@Cacheable註解中,通過key屬性來指定key,如上程式碼就表示只使用id作為快取的key,如果對key有複雜的要求,可以自定義keyGenerator。當然,Spring Cache中提供了root物件,可以在不定義keyGenerator的情況下實現一些複雜的效果:


示例:

@Service
//用來描述該類中所有方法使用的快取名稱
@CacheConfig(cacheNames = "yolo")
public class UserService {
    //表示將該方法的返回值快取起來
    @Cacheable
    public User getUserById(Integer id) {
        System.out.println("getUserById>>>" + id);
        User user = new User();
        user.setId(id);
        return user;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

測試快取:


可以看到方法只執行了一次,這是因為第二次呼叫並沒有去執行,使用的是快取結果。

當呼叫傳遞的引數不一樣時,會被認為是兩次不用的呼叫:


當指定 key時,會根據 key 的不同做出判斷,如果 兩次呼叫 key 相同,則只調用一次:

這裡雖然有多個引數,但是可以指定一個key,比如指定 id 為 key:

可以看到此時儘管傳遞的引數不同,但是隻呼叫了一次:

(3)自定義 keyGenerator

如果對 key 有複雜的要求,可以自定義 keyGenerator
比如這裡我想要的 key 格式為:方法名:引數

//自定義 keyGenerator,將返回值當做 key
@Component
public class MyKeyGenerator implements KeyGenerator {
    @Override
    public Object generate(Object o, Method method, Object... objects) {
        //可以根據自己的需求返回 key
        return method.getName() + ":" + Arrays.toString(objects);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9


儲存的key:

(4)@CacheEvict

這個註解一般加在刪除方法上,當資料庫中的資料刪除後,相關的快取資料也要自動清除,該註解在使用的時候也可以配置按照某種條件刪除(condition屬性)或者或者配置清除所有快取(allEntries屬性),示例程式碼如下:

  @CacheEvict
    public void deleteUserById(Integer id) {
        System.out.println("deleteUserById>>>" + id);
    }
  • 1
  • 2
  • 3
  • 4

可以看到第二次沒有使用快取,重新呼叫了一次:

(5)@CachePut

這個註解一般加在更新方法上,當資料庫中的資料更新後,快取中的資料也要跟著更新,使用該註解,可以將方法的返回值自動更新到已經存在的key上,示例程式碼如下:

  @CachePut(key = "#user.id")
    public User updateUserById(User user) {
        return user;
    }
  • 1
  • 2
  • 3
  • 4

可以看到只調用了一次,第二次直接使用的是快取,但是此時的快取是已經更新過的快取。

三、總結

在Spring Boot中,使用Redis快取,既可以使用RedisTemplate自己來實現,也可以使用使用這種方式,這種方式是Spring Cache提供的統一介面,實現既可以是Redis,也可以是Ehcache或者其他支援這種規範的快取框架。從這個角度來說,Spring Cache和Redis、Ehcache的關係就像JDBC與各種資料庫驅動的關係。