Redis筆記 - 01

之前用SpringBoot+MyBatisPlus+SpringMVC整合搭建了一個基礎web開發框架,使用這三個框架搭建出來項目結構非常的清爽,沒有過多的配置文件,各個模塊之間有清晰的聯繫,非常適合敏捷開發。

最近學習了Redis這個基於內存的,Key-Value數據形式的高性能數據庫,感覺學習了入門之後很簡單,沒有體會到它具體能幹嘛,我就想着使用Redis這個數據庫來整合之前搭建的框架,利用Spring中的緩存機制,將查詢的信息緩存到Redis中。

安裝Redis

Window 下安裝 下載地址:https://github.com/MSOpenTech/redis/releases。 Redis 支持32 位和64 位。這個需要根據你係統平臺的實際情況選擇,這裏我們下載 Redis-x64-xxx.zip壓縮包到 C盤的tools目錄中,解壓後,將文件夾重新命名爲 redis。

下載Redis版本

下載Redis版本

打開一個 cmd 窗口 使用cd命令切換目錄到 C:\tools\redis 運行 redis-server.exe redis.windows.conf 。
如果想方便的話,可以把 redis 的路徑加到系統的環境變量裏,這樣就省得再輸路徑了,後面的那個 redis.windows.conf 可以省略,如果省略,會啓用默認的。輸入之後,會顯示如下界面:

啓動成功後

啓動成功後

啓動成功後不要關閉命令窗口,不然redis服務也會關閉。如果不想每次使用都一直開着這個命令窗口,可以將redis服務添加到windows的服務中:

安裝命令:
redis-server.exe --service-install redis.windows.conf --loglevel verbose 
卸載命令:
redis-server --service-uninstall

 

安裝成功後,可以在windows的服務管理中對redis進行管理,就不用每次都打開命令窗口來啓動redis服務了,如下圖:

在windows中管理redis服務

在windows中管理redis服務

獲取之前項目

環境我就直接在之前的整合框架上進行搭建,springboot_mybatisplus
注意:之前搭建這個框架的時候我爲了獲取基礎數據,在啓動springboot的時候也啓動了爬蟲程序,如果不想每次啓動都啓動爬蟲可以註釋掉啓動類中的run方法。

添加Redis依賴到pom.xml中

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

在application.properties中添加配置

# REDIS (RedisProperties)
# Redis數據庫索引(默認爲0)
spring.redis.database=0
# Redis服務器地址
spring.redis.host=localhost
# Redis服務器連接端口
spring.redis.port=6379
# Redis服務器連接密碼(默認爲空)
spring.redis.password=
# 連接池最大連接數(使用負值表示沒有限制)
spring.redis.jedis.pool.max-active=8
# 連接池最大阻塞等待時間(使用負值表示沒有限制)
spring.redis.jedis.pool.max-wait=-1
# 連接池中的最大空閒連接
spring.redis.jedis.pool.max-idle=8
# 連接池中的最小空閒連接
spring.redis.jedis.pool.min-idle=0
# 連接超時時間(毫秒)
spring.redis.timeout=5000

我們需要做的配置到這裏就已經完成了,Spring Boot會在偵測到存在Redis的依賴並且Redis的配置是可用的情況下,使用RedisCacheManager初始化CacheManager。也就是說要使用緩存的話,SpringBoot就會選擇Redis來作爲緩存的容器。

編寫一個簡單的redis讀寫測試列

/**
 * redis讀寫測試
 * @author z77z
 *
 */
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = Application.class)
public class RedisCacheTest {
	@Autowired
	StringRedisTemplate stringRedisTemplate;
	
	@Test
	public void redisTest() throws Exception {
		//保存字符串
		stringRedisTemplate.opsForValue().set("aaa", "111");
		//讀取字符串
		String aaa = stringRedisTemplate.opsForValue().get("aaa");
		System.out.println(aaa);
	}
}

打印結果:

redis讀寫測試結果

redis讀寫測試結果

編寫緩存測試列

不使用緩存:

/**
 * 獲取數據,並且做緩存處理
 * @author z77z
 *
 */
@Component
public class RedisCache {
	
	@Autowired
	BeautifulPicturesService beautifulPicturesService;
	//@Cacheable(value = "BeautifulPictures")
	public BeautifulPictures getBeautifulPicturesList(String id) {
		return beautifulPicturesService.selectById(id);
	}
}
/**
 * 測試類
 * @author z77z
 *
 */
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = Application.class)
public class RedisCacheTest {
	@Autowired
	BeautifulPicturesService beautifulPicturesService;
	@Autowired
	StringRedisTemplate stringRedisTemplate;
	
	@Autowired
	RedisCache redisCache;
	
	@Test
	public void redisTest() throws Exception {
		//保存字符串
		stringRedisTemplate.opsForValue().set("aaa", "111");
		//讀取字符串
		String aaa = stringRedisTemplate.opsForValue().get("aaa");
		System.out.println(aaa);
	}
	
	@Test
	public void CacheTest() {
		BeautifulPictures beautifulPicture = redisCache.getBeautifulPicturesList("1011");
		System.out.println("第一次查詢結果:");
		System.out.println(beautifulPicture);
		BeautifulPictures beautifulPicture1 = redisCache.getBeautifulPicturesList("1011");
		System.out.println("第二次查詢結果:");
		System.out.println(beautifulPicture1);
	}
}

執行結果:

不使用緩存測試結果

可以從日誌中看出兩次查詢都是執行了sql,也就是執行了getBeautifulPicturesList這個方法

使用緩存:

在getBeautifulPicturesList方法的上面添加@Cacheable(value = “BeautifulPictures”)註解,當請求這個方法時會先判斷緩存中是否存在,存在就在緩存中獲取,不會執行這個方法。不存在就正常執行這個方法獲取返回值並且存如緩存中。添加註解後執行結果如下:

添加緩存註釋後

添加緩存註釋後

從日誌中可以看出,第一次查詢的時候執行的sql,而第二次查詢的時候沒有執行sql,說明是從緩存中獲取的數據。

緩存數據一致性保證

CRUD (Create 創建,Retrieve 讀取,Update 更新,Delete 刪除) 操作中,除了 R具備冪等性,其他三個發生的時候都可能會造成緩存結果和數據庫不一致。爲了保證緩存數據的一致性,在進行 CUD 操作的時候我們需要對可能影響到的緩存進行更新或者清除。如下:

/**
 * 獲取數據,並且做緩存處理
 * @author z77z
 *
 */
@Component
public class RedisCache {
	
	@Autowired
	BeautifulPicturesService beautifulPicturesService;
	
	//查詢
	@Cacheable(value = "beautifulPictures")
	public BeautifulPictures getBeautifulPicturesList(String id) {
		return beautifulPicturesService.selectById(id);
	}
	
	//修改
	@CachePut(value = "beautifulPictures")
	public void updateBeautifulPicture(String id) {
		BeautifulPictures beautifulPictures = new BeautifulPictures();
		beautifulPictures.setTitle("Title被我修改了一下,哈哈");
		beautifulPictures.setId(id);
		beautifulPicturesService.updateById(beautifulPictures);
	}
}

 

/**
 * 測試類
 * @author z77z
 *
 */
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = Application.class)
public class RedisCacheTest {
	@Autowired
	BeautifulPicturesService beautifulPicturesService;
	@Autowired
	StringRedisTemplate stringRedisTemplate;
	
	@Autowired
	RedisCache redisCache;
	
	@Test
	public void redisTest() throws Exception {
		//保存字符串
		stringRedisTemplate.opsForValue().set("aaa", "111");
		//讀取字符串
		String aaa = stringRedisTemplate.opsForValue().get("aaa");
		System.out.println(aaa);
	}
	
	@Test
	public void CacheTest() {
		String id = "1";
		BeautifulPictures beautifulPicture = redisCache.getBeautifulPicturesList(id);
		System.out.println("第一次查詢結果:");
		System.out.println(beautifulPicture);
		BeautifulPictures beautifulPicture1 = redisCache.getBeautifulPicturesList(id);
		System.out.println("第二次查詢結果:");
		System.out.println(beautifulPicture1);
		
		redisCache.updateBeautifulPicture(id);
		
		BeautifulPictures beautifulPicture2 = redisCache.getBeautifulPicturesList(id);
		System.out.println("第三次查詢結果:");
		System.out.println(beautifulPicture2);
	}
}

保持緩存一致性測試結果:

保持緩存的一致性測試

保持緩存的一致性測試

在會導致數據發生改變的方法上添加@CachePut(value = "beautifulPictures")註解,添加後會更新緩存中的值,並且每次都會正常執行方法內容。

SpringBoot緩存註解詳解

  • @Cacheable:作用是主要針對方法配置,能夠根據方法的請求參數對其結果進行緩存

主要參數說明:

  1. value:緩存的名稱,在 spring 配置文件中定義,必須指定至少一個,例如:@Cacheable(value=”mycache”) 或者 @Cacheable(value={”cache1”,”cache2”}。
  2. key:緩存的 key,可以爲空,如果指定要按照 SpEL 表達式編寫,如果不指定,則缺省按照方法的所有參數進行組合,例如:@Cacheable(value=”testcache”,key=”#userName”)。
  3. condition:緩存的條件,可以爲空,使用 SpEL 編寫,返回 true 或者 false,只有爲 true 才進行緩存,例如:@Cacheable(value=”testcache”,condition=”#userName.length()>2。
  • @CachePut:作用是主要針對方法配置,能夠根據方法的請求參數對其結果進行緩存,和 @Cacheable 不同的是,它每次都會觸發真實方法的調用

主要參數說明:

  1. valuekeycondition參數配置和@Cacheable一樣。
  • @CacheEvict:作用是主要針對方法配置,能夠根據一定的條件對緩存進行清空

主要參數說明:

  1. valuekeycondition參數配置和@Cacheable一樣。
  2. allEntries:是否清空所有緩存內容,缺省爲 false,如果指定爲 true,則方法調用後將立即清空所有緩存,例如:@CachEvict(value=”testcache”,allEntries=true)。
  3. beforeInvocation:是否在方法執行前就清空,缺省爲 false,如果指定爲 true,則在方法還沒有執行的時候就清空緩存,缺省情況下,如果方法執行拋出異常,則不會清空緩存,例如@CachEvict(value=”testcache”,beforeInvocation=true)。

另外說下: @cache(“something”);這個相當於save()操作,@cachePut相當於Update()操作,只要他標示的方法被調用,那麼都會緩存起來,而@cache則是先看下有沒已經緩存了,然後再選擇是否執行方法。@CacheEvict相當於Delete()操作。用來清除緩存用的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章