spring-boot -快取註解
阿新 • • 發佈:2020-08-16
快取:商品資訊放到快取中介軟體中,
驗證碼幾秒鐘有效也是放在快取中介軟體。
快取規範
互動流程:
如果需要使用jRS107需要匯入包:
java.cache.cache-api
JSR107提供的是介面,如果需要用那些快取的元件,就需要加入對應的實現,
如果沒有對應的實現的話,是需要自己寫的。
spring裡面提供了快取抽象,
CacheAutoConfiguration 加入的自動配置類
預設加入SimpleCacheConfiguration
@Configuration( proxyBeanMethods = false) @ConditionalOnMissingBean({CacheManager.class}) @Conditional({CacheCondition.class}) class SimpleCacheConfiguration { SimpleCacheConfiguration() { } @Bean ConcurrentMapCacheManager cacheManager(CacheProperties cacheProperties, CacheManagerCustomizers cacheManagerCustomizers) { ConcurrentMapCacheManager cacheManager= new ConcurrentMapCacheManager(); List<String> cacheNames = cacheProperties.getCacheNames(); if (!cacheNames.isEmpty()) { cacheManager.setCacheNames(cacheNames); } return (ConcurrentMapCacheManager)cacheManagerCustomizers.customize(cacheManager); } }
使用快取註解的前提是:
配置檔案:
spring.datasource.url=jdbc:mysql://192.168.1.102:3306/mybatis spring.datasource.username=root spring.datasource.password=1997 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver #開啟駝峰命名 mybatis.configuration.map-underscore-to-camel-case=true logging.level.root=debug
開啟debug模式可以檢視更加細節的日誌
加入依賴:
<dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.3</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency>
建立資料庫表:
CREATE TABLE `employee` ( `id` int(11) NOT NULL AUTO_INCREMENT, `lastName` varchar(255) DEFAULT NULL, `email` varchar(255) DEFAULT NULL, `gender` int(2) DEFAULT NULL, `d_id` int(11) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
實體類:
public class Employee { private Integer id; private String lastName; private Integer gender; private String email; private Integer dId; public Employee() { super(); } public Employee(Integer id, String lastName, Integer gender, String email, Integer dId) { super(); this.id = id; this.lastName = lastName; this.gender = gender; this.email = email; this.dId = dId; } public void setId(Integer id) { this.id = id; } public void setLastName(String lastName) { this.lastName = lastName; } public void setGender(Integer gender) { this.gender = gender; } public void setEmail(String email) { this.email = email; } public void setdId(Integer dId) { this.dId = dId; } public Integer getId() { return id; } public String getLastName() { return lastName; } public Integer getGender() { return gender; } public String getEmail() { return email; } public Integer getdId() { return dId; } @Override public String toString() { return "Employee{" + "id=" + id + ", lastName='" + lastName + '\'' + ", gender=" + gender + ", email='" + email + '\'' + ", dId=" + dId + '}'; } }
mapper介面
@Mapper public interface EmployeeMapper { @Select("select * from employee where id = #{id}") public Employee getEmpById(Integer id); @Update("update employee set lastName =#{lastName},email=#{email},gender=#{gender},d_id=#{dId}") public void updateEmp(Employee employee); @Delete("delete from employee where id =#{id}") public void deleteEmpById(Integer id); @Insert("insert into employee(lastName,email,gender,d_id) values(#{lastName},#{email},#{gender},#{dId})") public void insertEmp(Employee employee); @Select("select * from employee where lastName = #{lastname}") Employee getEmpByLastName(String lastname); }
controller層:
@RestController public class EmplloyeeController { @Autowired EmployeeService employeeService; @RequestMapping("/emp/{id}") public Employee getEmployee(@PathVariable("id") Integer id){ return employeeService.getEmp(id); } @RequestMapping("/emp") public Employee update(Employee employee){ Employee employee1 =employeeService.updateEmp(employee); return employee1; } @RequestMapping("/delemp") public String deleteEMp(Integer id){ employeeService.deleteEmp(id); return "success"; } }
在服務層我們使用快取註解:
先開啟快取註解@EnableCaching,,在啟動類中
@Cacheable
@Cacheable(cacheNames = "emp",keyGenerator = "myKeyGenerator") public Employee getEmp(Integer id){ System.out.println("chanxun"+id+"員工"); Employee emp = employeeMapper.getEmpById(id); return emp; }
@Cacheable標註的方法執行之前先來檢查快取中有沒有這個資料,預設按照引數的值作為key去查詢快取
如果有就不需要執行函式
如果沒有就執行函式
*/
@Cacheable執行流程:
執行的流程: 1方法執行之前,先去查詢Cache元件,安裝cacheNames指定的名字獲取 (CacheManager先獲取相應的快取)第一次獲取快取,回自動創建出來,以後就能用了 2去Cache中查詢快取的內容弄給,使用一個key,預設是方法的引數 key是按照某個規則生成的,預設是keyGenerator生成,預設使用simplekeyGenerator simplekeyGenerator策略: 如果沒有引數,key= new SimpleKey 如果一個:使用它 如果多個,SimpleKey(params) 3 沒有查到快取就呼叫目標方法 4將目標方法返回的結果,放進快取中
@Cacheable的屬性和作用:
/** * 將方法的允許結果進行快取,以後如果要相同的資料,直接從快取中獲取,不用呼叫方法 *CacheManager 管理多個Cache元件,對快取的真正CRUD操作是在Cache元件中, * 每一個快取元件有自己的唯一名字 * 幾個屬性: * cacheNames/value:指定快取元件的名字,將方法的返回結果放在哪個快取中,陣列,可自定多個快取 * key:快取資料使用的key,可以用它來指定,預設是使用方法引數的值 1 * 可以使用SpEl格式 * keyGenerator:key的生成器,可以自己指定key的生成器元件id * key和keyGenerator二選一,!!可以自己指定 * CacheManager:指定快取管理器 * condition,指定符合條件的情況菜快取 condiction ="#id>0"id的值大於0才快取 * unless :否定快取,當unless指定的條件為true,返回值不會被快取,可以獲取到結果進行判斷 * unless = ”#result == null“如果結果為null 不快取 * sync:是否使用非同步模式
@CachePut:
/** * @CachePut 既呼叫方法,又跟新快取資料 * 場景:修改資料庫的某個資料,同時跟新快取 * 執行實際:1先呼叫目標方法 * 2將目標方法的結果快取起來 測試: 1查詢1好員工,,查到的結果回放到快取當中 儲存方式:key:1 value:員工資訊 2以後查詢還是之前的結果 3更新1號員工http://localhost:8080/emp?id=1&lastName=quanzhiqiang&gender=2 儲存方式:key:傳入的物件emloyee,value: 返回的employee物件 4查詢1號員工?? 理論上查詢的應該是更新後的員工資訊 但是結果是之前的資訊,原因可以看看上面的快取儲存的兩種方式就知道了 解決方法, @CachePut(value = "emp" ,key = "#employee.id"),指定修改的key */
改進後:
@CachePut(value = "emp" ,key = "#result.id") public Employee updateEmp(Employee employee){ System.out.println("updateEmp"+employee); employeeMapper.updateEmp(employee); return employee; } }
//注意:你取快取的key和我們更新快取的key應該一致
@CacheEvict
/** * @CacheEvict 快取請除 * key:通過key來指定清楚的資料 * allEntries = true:指定清除這個快取中的所有的資料 * beforeInvocation = false:快取的清楚是否在方法之前執行 * 預設代表方法執行之後執行,出現異常快取不會清除。 */
@CacheEvict(value = "emp",key = "#id") public void deleteEmp(Integer id){ System.out.println("deleteEmp:"+id); employeeMapper.deleteEmpById(id); }
@Caching:
可以同時定義多個快取註解:
@Caching( cacheable = { @Cacheable(value = "emp",key = "#lastname") }, put = { @CachePut(value = "emp",key = "#result.id"), @CachePut(value = "emp",key = "#result.lastName") } ) public Employee getEmpByLastName(String lastname){ return employeeMapper.getEmpByLastName(lastname); } }
@CacheConfig
/* 因為每個快取註解都要寫value =”emp" 所以我們可以通過@CacheConfig註解統一設定 */ @CacheConfig(cacheNames = "emp") 加在類上就可以了,裡面的方法的快取註解都不需要指定快取元件名i在