一、Spring Cache 概述?
Spring Cache 并不是一個具體的緩存實現方案,而是一套抽象的緩存規范。它支持多種緩存技術,如 Ehcache、Redis、Caffeine 等,開發者可以根據項目需求靈活選擇合適的緩存技術。其核心思想是通過在方法上添加注解,在方法調用前后自動完成緩存的操作,例如查詢數據時優先從緩存中獲取,數據更新時同步更新緩存,從而避免重復執行方法和數據庫查詢,提升系統性能和響應速度。?
Spring Cache 的工作流程大致如下:當被緩存注解標注的方法被調用時,Spring Cache 會先檢查緩存中是否存在對應的數據。如果存在,直接從緩存中返回數據,不再執行方法體;如果不存在,則執行方法體,獲取數據,并將數據存入緩存,以便下次使用。這種 “先查緩存,后執行方法” 的機制,大大減少了數據庫的負載和方法的執行次數。?
相關Maven坐標
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId>
</dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope>
</dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.2.0</version>
</dependency>
二、@EnableCaching 注解?
@EnableCaching 是開啟 Spring Cache 功能的關鍵注解,通常被添加到 Spring Boot 項目的配置類上,用于啟用緩存功能。只有在配置類上添加了該注解,Spring 才會識別并處理其他緩存相關的注解。?
添加 @EnableCaching 注解后,Spring 會自動掃描項目中帶有緩存注解的方法,并在方法調用時,按照緩存規則進行相應的緩存操作。它就像是一把鑰匙,開啟了 Spring 框架中緩存功能的大門,讓開發者能夠使用各種緩存注解來簡化開發過程。?
三、@Cacheable 注解?
@Cacheable 是 Spring Cache 中最常用的注解之一,它主要用于標注查詢方法。當方法被標注 @Cacheable 后,Spring 在調用該方法時,會首先檢查指定的緩存中是否存在對應的數據。如果存在,直接從緩存中返回數據,不再執行方法體;如果不存在,則執行方法體獲取數據,并將數據存入緩存,以便后續使用。?
@GetMapping//在方法執行前,先查詢緩存,若沒有執行方法,并且把數據放入緩存//若查到了,會去代理方法內執行,就不會執行原方法@Cacheable(cacheNames = "userCache",key = "#id")public User getById(Long id){User user = userMapper.getById(id);return user;}
在上述代碼中,@Cacheable 注解的 value 屬性指定了緩存的名稱(這里是 users),key 屬性定義了緩存的鍵(這里使用方法參數 id 作為鍵)。這意味著,每次調用 getUserById 方法時,Spring 會根據 id 值在 users 緩存中查找數據。如果找到,直接返回;找不到則執行方法從數據庫查詢,并將結果存入緩存。通過 @Cacheable 注解,我們可以輕松實現查詢方法的緩存功能,減少數據庫的壓力。?
四、@CachePut 注解?
@CachePut 注解用于更新緩存數據。與 @Cacheable 不同,@CachePut 無論緩存中是否存在數據,都會先執行方法體,獲取最新的數據,然后將數據更新到緩存中。這一特性使得 @CachePut 非常適合用于數據更新的場景,例如修改用戶信息后,及時將最新的用戶數據更新到緩存中。?
@PostMapping//把方法的返回值放到緩存當中//key為userCache::user的id//這里方法開始執行時,user內并沒有id key也不會生成,等數據庫插入好數據,并且id賦值給User才//開始構造key 再把數據放入緩存中@CachePut(cacheNames = "userCache",key = "#user.id")
// @CachePut(cacheNames = "userCache",key = "#result.id") //返回值的id
// @CachePut(cacheNames = "userCache",key = "#p0.id") //第一個參數的id
// @CachePut(cacheNames = "userCache",key = "#a0.id") //第一個參數的id
// @CachePut(cacheNames = "userCache",key = "#root.args[0].id") //第一個參數的idpublic User save(@RequestBody User user){userMapper.insert(user);return user;}
在上述示例中,當調用 updateUser 方法更新用戶信息時,方法執行完成后,返回的最新用戶數據會被存入 users 緩存中,鍵為用戶的 id。這樣,后續查詢該用戶信息時,就能從緩存中獲取到最新的數據,保證了緩存數據與數據庫數據的一致性。?
五、@CacheEvict 注解?
@CacheEvict 注解用于從緩存中刪除數據。當方法被標注 @CacheEvict 后,在方法執行完成時,Spring 會根據注解配置,從指定的緩存中刪除相應的數據。它主要用于數據刪除、修改等導致緩存數據失效的場景,以確保緩存中不會存在過期或無效的數據。?
@DeleteMapping//方法執行后,刪除指定緩存@CacheEvict(cacheNames = "userCache",key = "#id",beforeInvocation=true)public void deleteById(Long id){userMapper.deleteById(id);}@DeleteMapping("/delAll")//方法執行后,刪除在userCache下的全部緩存@CacheEvict(cacheNames = "userCache",allEntries = true,beforeInvocation=true)public void deleteAll(){userMapper.deleteAll();}
在上述代碼中,當調用 deleteUser 方法刪除用戶時,方法執行完成后,Spring 會從 users 緩存中刪除鍵為 id 的數據。此外,@CacheEvict 還支持一些其他屬性,如 allEntries = true,用于清空整個緩存;beforeInvocation = true,用于在方法執行前就刪除緩存,即使方法執行過程中拋出異常,緩存也會被刪除。