spring boot2 (28)-cache緩存

數據庫的數據是存儲在硬盤上的,頻繁訪問性能較低。而緩存數據存儲在內存中,訪問性能比硬盤快了一個數量級。如果將一些需要頻繁查詢的熱數據放到緩存中,可以大大減輕數據庫的訪問壓力。

pom.xml

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

啓用緩存

在配置類中添加以下註解

@EnableCaching

使用緩存

出於方便,這裏直接在控制層做緩存。
	@GetMapping("/find")
	@Cacheable(cacheNames = "hello") 
	public String find() {
		System.out.println("從數據庫查詢數據,並用return返回");
		return "該數據會被緩存";
	}
  • @Cacheable:指在執行find方法前,首先查找該方法是否有緩存,如果有則直接返回緩存,如果沒有則執行方法。
  • cacheNames:指定緩存的名稱,不同緩存的數據是彼此隔離的。

緩存的key

上面cacheNames指定了緩存名稱,但是每個方法由於傳參不同,其return數據也會不同,所以一個方法中可能會有多個緩存。要在同一個cacheNames中區別不同的緩存,就需要使用key。修改前兩行代碼,給find方法傳入了一個User,這是我自定義的類,其中有一個id參數。同時指定了key爲"#user.id",這是SpEL表達示,指使用user的id作爲當前緩存的key。關於SpEL更多 語法可自行百度。

@GetMapping("/find")	
@Cacheable(cacheNames = "hello",key = "#user.id") 
public String find(User user) {
  • 現在訪問http://localhost:8080/find?id=1,此時id參數會傳入user,最終該緩存的key爲1。
  • 然後訪問http://localhost:8080/find?id=2,此緩存的key爲2,與上面的1不一樣,所以它們不是同一個緩存。

修改緩存

	@GetMapping("/update")
	@CachePut(cacheNames = "hello", key = "#id") 
	public String update(String id) {
		System.out.println("讀取修改後的數據");
		return "修改後的緩存數據";
	}
  • @CachePut:無論是否存在緩存,它都會執行,而且用return數據刷新緩存。
  • cacheNames:指定要修改的key所屬的cacheNames。
  • key:這裏方法參數就是id,所以可以直接用#id。

訪問http://localhost:8080/update?id=1,此時key爲1的緩存將被修改。之後再訪問http://localhost:8080/find?id=1,都會得到修改後的數據,find方法中原有的數據被替換了。

刪除緩存

訪問http://localhost:8080/delete?id=1,即可刪除key爲1的緩存,和上面一樣的原理。

	@GetMapping("/delete")
	@CacheEvict(cacheNames = "hello", key = "#id") 
	public String delete(String id) {
		return "刪除成功";
	}

condition條件

如果只想將id爲1的查詢寫入緩存,而其他數據不需要緩存。可以添加condition緩存條件,如下。這裏id參數是個字符串型,所以加了單引號,否則1就是整數,條件不成立。
@Cacheable(cacheNames = "hello",key="#user.id",condition ="#user.id=='1'" ) 

此時,只有訪問http://localhost:8080/find?id=1纔會使用緩存,如果id爲其他值將不使用緩存。

unless條件

condition是在調用方法之前判斷條件,決定是否緩存。unless是在調用方法之後判斷條件,決定是否不緩存。

	@GetMapping("/find")
	@Cacheable(cacheNames = "hello",unless="#result.id.contains('1')" ) 
	public User find(String id) {
		System.out.println("從數據庫查詢數據");
		User user = new User();
		user.setId(id);
		return user;
	}
  • unless:如果SpEL條件成立,則不緩存。
  • #result.id.contains:result指方法return的數據,id指return的user的id參數,contains指id的值是否包含'1',如果包含則unless條件成立,不進行緩存。

caffeine

spring boot支持多種不同的緩存供應商。在默認情況下使用的是簡單緩存,不建議在正式環境使用。我們可以配置一些更加強大的緩存,比如Hibernate的默認緩存EhCache等,而caffeine則是基於java8新出的一個高性能緩存,官方稱其接近完美。下面就來介紹在spring boot中集成caffeine。

		<dependency>
			<groupId>com.github.ben-manes.caffeine</groupId>
			<artifactId>caffeine</artifactId>
		</dependency>

在pom.xml中增加以上依賴,spring boot就會自動用caffeine替換默認的簡單緩存,用法都是一樣的。

properties參數配置

spring.cache.type=caffeine
spring.cache.cache-names=hello,world
spring.cache.caffeine.spec=maximumSize=1,expireAfterAccess=5s
  • spring.cache.type:指定使用哪個緩存供應商
  • spring.cache.cache-names:在啓動時創建緩存名稱,即前面的cacheNames,多個名稱用逗號分隔。
  • spring.cache.caffeine.spec:這是caffeine緩存的專用配置。
  • maximumSize=1:最大緩存數量,假如有緩存1,再寫入緩存2時,就有2個緩存,超出最大數量,緩存1就會被清除。
  • expireAfterAccess=5s:緩存5秒,即緩存在5秒之內沒有被使用,就會被清除。

默認情況下,緩存的數據會一直保存在內存中,有些數據可能用一次後很長時間都不會再用,這樣會有大量無用的數據長時間佔用內存,通過配置properties可以及時清除不需要的緩存。

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