JSR-107、Spring緩存抽象、整合Redis
在用官方語言進行解釋這個東西之前,我先說說我對緩存的理解,緩存就是當我們在進行與數據庫多次交互的時候,為了方便我們的使用,將我們在數據庫里面查詢到的東西存放在一個地方,當我們,再次進行使用的時候可以減少我們對於數據庫的操作,提高效率,
下面開始步入正題。
一、JSR107
- Java Caching定義了5個核心接口,分別是CachingProvider, CacheManager, Cache, Entry 和 Expiry。
- CachingProvider定義了創建、配置、獲取、管理和控制多個CacheManager。一個應用可以在運行期訪問多個CachingProvider。
- CacheManager定義了創建、配置、獲取、管理和控制多個唯一命名的Cache,這些Cache存在於CacheManager的上下文中。一個CacheManager僅被一個CachingProvider所擁有。
- Cache是一個類似Map的數據結構並臨時存儲以Key為索引的值。一個Cache僅被一個CacheManager所擁有。
- Entry是一個存儲在Cache中的key-value對。
- Expiry 每一個存儲在Cache中的條目有一個定義的有效期。一旦超過這個時間,條目為過期的狀態。一旦過期,條目將不可訪問、更新和刪除。緩存有效期可以通過ExpiryPolicy設置。
這里有一張圖示:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-yrtlZwhC-1581770692107)(http://39.102.36.205:8090/upload/2020/2/image-b3a517e510a54c098743b4a12c90ec89.png)]
二、Spring緩存抽象
- Spring從3.1開始定義了org.springframework.cache.Cache
和org.springframework.cache.CacheManager接口來統一不同的緩存技術;
並支持使用JCache(JSR-107)注解簡化我們開發 - Cache接口為緩存的組件規范定義,包含緩存的各種操作集合;Cache接口下Spring提供了各種xxxCache的實現;如RedisCache,EhCacheCache , ConcurrentMapCache等;
- 每次調用需要緩存功能的方法時,Spring會檢查檢查指定參數的指定的目標方法是否已經被調用過;如果有就直接從緩存中獲取方法調用后的結果,如果沒有就調用方法並緩存結果后返回給用戶。下次調用直接從緩存中獲取。
使用Spring緩存抽象時我們需要關注以下兩點;
1、確定方法需要被緩存以及他們的緩存策略
2、從緩存中讀取之前緩存存儲的數據
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-FQBLgSkR-1581770692110)(http://39.102.36.205:8090/upload/2020/2/image-9381229182494d0ea1b77e4d8bc947b6.png)]
三、幾個重要概念&緩存注解
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-zU5AXHyV-1581770692111)(http://39.102.36.205:8090/upload/2020/2/image-ff11732d786e41ed9ed667b0e9fce73d.png)]
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-yblLafew-1581770692112)(http://39.102.36.205:8090/upload/2020/2/image-a56ea0f690f24f108224571bb96c87f1.png)]
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-DA9dUNa1-1581770692112)(http://39.102.36.205:8090/upload/2020/2/image-b41c7eb6071946bbb9e036f3336e0304.png)]
四、緩存使用
1、引入spring-boot-starter-cache模塊
2、@EnableCaching開啟緩存
3、使用緩存注解
4、切換為其他緩存
**
* 一、搭建基本環境
* 1、導入數據庫文件 創建出department和employee表
* 2、創建javaBean封裝數據
* 3、整合MyBatis操作數據庫
* 1.配置數據源信息
* 2.使用注解版的MyBatis;
* 1)、@MapperScan指定需要掃描的mapper接口所在的包
* 二、快速體驗緩存
* 步驟:
* 1、開啟基於注解的緩存 @EnableCaching
* 2、標注緩存注解即可
* @Cacheable
* @CacheEvict
* @CachePut
* 默認使用的是ConcurrentMapCacheManager==ConcurrentMapCache;將數據保存在 ConcurrentMap<Object, Object>中
* 開發中使用緩存中間件;redis、memcached、ehcache;
* 三、整合redis作為緩存
* Redis 是一個開源(BSD許可)的,內存中的數據結構存儲系統,它可以用作數據庫、緩存和消息中間件。
* 1、安裝redis:使用docker;
* 2、引入redis的starter
* 3、配置redis
* 4、測試緩存
* 原理:CacheManager===Cache 緩存組件來實際給緩存中存取數據
* 1)、引入redis的starter,容器中保存的是 RedisCacheManager;
* 2)、RedisCacheManager 幫我們創建 RedisCache 來作為緩存組件;RedisCache通過操作redis緩存數據的
* 3)、默認保存數據 k-v 都是Object;利用序列化保存;如何保存為json
* 1、引入了redis的starter,cacheManager變為 RedisCacheManager;
* 2、默認創建的 RedisCacheManager 操作redis的時候使用的是 RedisTemplate<Object, Object>
* 3、RedisTemplate<Object, Object> 是 默認使用jdk的序列化機制
* 4)、自定義CacheManager;
*
*/
五、整合redis實現緩存
- 引入spring-boot-starter-data-redis
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-K9Mh87aW-1581770692113)(http://39.102.36.205:8090/upload/2020/2/image-410e0dc463d24a0ba9f20827812418b0.png)] - application.yml配置redis連接地址
spring.redis.host=118.24.44.169
- 使用RestTemplate操作redis
- redisTemplate.opsForValue();//操作字符串
- redisTemplate.opsForHash();//操作hash
- redisTemplate.opsForList();//操作list
- redisTemplate.opsForSet();//操作set
- redisTemplate.opsForZSet();//操作有序set
- 配置緩存、CacheManagerCustomizers
- 測試使用緩存、切換緩存、 CompositeCacheManager
- redis常見的五大數據類型
/**
* Redis常見的五大數據類型
* String(字符串)、List(列表)、Set(集合)、Hash(散列)、ZSet(有序集合)
* stringRedisTemplate.opsForValue()[String(字符串)]
* stringRedisTemplate.opsForList()[List(列表)]
* stringRedisTemplate.opsForSet()[Set(集合)]
* stringRedisTemplate.opsForHash()[Hash(散列)]
* stringRedisTemplate.opsForZSet()[ZSet(有序集合)]
*/
//序列化器的作用將對象保存在redis中的時候通過json字符串的形式進行展示。
//操作員工的
@Bean
public RedisTemplate<Object, Employee> empRedisTemplate(
RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
RedisTemplate<Object, Employee> template = new RedisTemplate<Object, Employee>();
//序列化器
template.setConnectionFactory(redisConnectionFactory);
Jackson2JsonRedisSerializer<Employee> ser = new Jackson2JsonRedisSerializer<Employee>(Employee.class);
template.setDefaultSerializer(ser);
return template;
}
//CacheManagerCustomizers可以來定制緩存的一些規則
//自定義員工的緩存模擬器,將上個方法當成參數放進里面,進行自動注入
@Primary //將某個緩存管理器作為默認的
@Bean
public RedisCacheManager employeeCacheManager(RedisTemplate<Object, Employee> empRedisTemplate){
RedisCacheManager cacheManager = new RedisCacheManager(empRedisTemplate);
//key多了一個前綴
//使用前綴,默認會將CacheName作為key的前綴
cacheManager.setUsePrefix(true);
return cacheManager;
}
順便說一下我的個人博客地址: