接上一節。
@CachePut:既調用方法,又更新緩存。
使用場景:當更改了數據庫的某個數據,同時也更新緩存。
運行時機:先調用目標方法,然后將結果放入緩存。
package com.gong.springbootcache.controller; import com.gong.springbootcache.bean.Employee; import com.gong.springbootcache.service.EmployeeService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.CachePut; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; @Controller public class EmployeeController { @Autowired EmployeeService employeeService; //value:指定緩存的名字,每個緩存組件有一個唯一的名字。緩存組件由CacheManager進行管理。 //key:緩存數據時用到的key,默認使用方法參數的值,1-方法返回值 key = //#id也可這么表示:#root.args[0](第一個參數) //keyGenerator:指定生成緩存的組件id,使用key或keyGenerator其中一個即可 //cacheManager,cacheResolver:指定交由哪個緩存管理器,使用其中一個參數即可 //condition:指定符合條件時才進行緩存 //unless:當unless指定的條件為true,方法的返回值就不會被緩存 //sync:是否使用異步模式 //"#root.methodName+'[+#id+]'" @Cacheable(value = "emp") @ResponseBody @RequestMapping("/emp/{id}") public Employee getEmp(@PathVariable("id") Integer id){ Employee emp = employeeService.getEmp(id); return emp; } @CachePut(value = "emp") @GetMapping("/emp") public Employee updateEmp(Employee employee){ Employee emp = employeeService.updateEmp(employee); return emp; } }
第一次查詢:
沒有使用緩存。
第二次查詢:使用到了緩存,不必再發送sql。
然后進行更新:
先執行了方法,也就是會發送sql:
然后我們再執行一次查詢:
此時我們查詢出來的是從緩存中獲取的,但是,為什么緩存沒有進行更新呢?
這是因為getEmp中參數為id,updateEmp參數中為employee。我們知道,如果使用緩存時不指定緩存的key,也就是設置key或者keyGenerator屬性,那么,緩存的key就是方法中參數的組合,所以,若果要實現同步的話,我們要指定緩存的key為相同的值。
我們只需要將updateEmp方法中的CachePut注解中加上:key="#employee.id"。
此時再按照之前的步驟再來一次,記得先把2號員工的數據先改回去,在修改后再進行查詢:
得到了我們想要的值,同時也沒有發送sql。