本章給大家帶來的是SpringBoot和緩存的學習。同時已經錄製了非常詳細的視頻,如果看文檔較爲喫力,可以結合視頻進行學習,幫你快速掌握SringBoot與緩存。
目錄
一、JSR107
二、Spring緩存抽象
三、幾個重要概念&緩存註解
四、緩存使用
五、整合redis實現緩存
六、整合一個實例
一、JSR107
Java Caching定義了5個核心接口,分別是CachingProvider, CacheManager, Cache, Entry 和 Expiry。
- CachingProvider 定義了創建、配置、獲取、管理和控制多個 CacheManager 。一個應用可以在運行期訪問多個 CachingProvider 。
- CacheManager 定義了創建、配置、獲取、管理和控制多個唯一命名的 Cache ,這些 Cache 存在於 CacheManager 的上下文中。一個 CacheManager 僅被一個 CachingProvider 所擁有。
- Cache 是一個類似 Map 的數據結構並臨時存儲以 Key 爲索引的值。一個 Cache 僅被一個 CacheManager 所擁有。
- Entry 是一個存儲在 Cache 中的 key-value 對。
- Expiry 每一個存儲在 Cache 中的條目有一個定義的有效期。一旦超過這個時間,條目爲過期的狀態。一旦過期,條目將不可訪問、更新和刪除。緩存有效期可以通過 ExpiryPolicy 設置。
二、Spring緩存抽象
Spring從3.1開始定義了
org.springframework.cache.Cache
和
org.springframework.cache.CacheManager接口來統一不同的緩存技術;
並支持使用JCache(JSR-107)註解簡化我們的開發;
- Cache 接口爲緩存的組件規範定義,包含緩存的各種操作集合;
- Cache 接口下 Spring 提供了各種 xxxCache 的實現;如 RedisCache , EhCacheCache , ConcurrentMapCache 等;
- 每次調用需要緩存功能的方法時, Spring 會檢查指定參數的指定的目標方法是否已經被調用過;如果有就直接從緩存中獲取方法調用後的結果,如果沒有就調用方法並緩存結果後返回給用戶。下次調用直接從緩存中獲取。
- 使用 Spring 緩存抽象時我們需要關注以下兩點;
1、確定方法需要被緩存以及它們的緩存策略
2、從緩存中讀取之前緩存存儲的數據
三、幾個重要概念&緩存註解
SpEL語法的緩存格式
四、緩存使用
• 1 、引入 spring-boot-starter-cache 模塊
• 2 、 @ EnableCaching 開啓緩存
• 3 、使用緩存註解
• 4 、切換爲其他緩存
測試緩存對象:
五、整合redis實現緩存
\1. 引入 spring-boot-starter-data- redis 、 spring-data- redis
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
\2. 配置redis連接地址spring.redis.host=192.168.0.108
\3. 使用ReditTemplate操作redis
\1. redisTemplate.opsForValue ();// 操作字符串
\2. redisTemplate.opsForHash ();// 操作 hash
\3. redisTemplate.opsForList ();// 操作 list
\4. redisTemplate.opsForSet ();// 操作 set
\5. redisTemplate.opsForZSet ();// 操作有序 set
redisconfig實現:
@Configuration
public class RedisConfig {
//過期時間
private Duration timeToLive = Duration.ofDays(1);
@Bean
public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory){
RedisCacheConfiguration configuration = RedisCacheConfiguration.defaultCacheConfig().entryTtl(timeToLive)
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(keySerializer()))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(valueSerializer()))
.disableCachingNullValues();
RedisCacheManager redisCacheManager = RedisCacheManager.builder(connectionFactory)
.cacheDefaults(configuration).transactionAware().build();
return redisCacheManager;
}
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
template.setKeySerializer(keySerializer());
template.setHashKeySerializer(keySerializer());
template.setValueSerializer(valueSerializer());
template.setHashValueSerializer(valueSerializer());
return template;
}
private RedisSerializer<String> keySerializer(){
return new StringRedisSerializer();
}
private RedisSerializer<Object> valueSerializer(){
return new GenericJackson2JsonRedisSerializer();
}
}
application.properties的配置:
spring.datasource.username=spring
spring.datasource.password=spring
#開啓駝峯命名匹配規則
mybatis.configuration.map-underscore-to-camel-case=true
logging.level.com.dahaiwuliang.cache.mapper=debug
#redis連接
spring.redis.host=192.168.0.108
六、整合一個實例
controller層:
@RestController
public class EmployeeController {
@Autowired
EmployeeService employeeService;
@GetMapping("/getEmployee")
public Employee getEmployee(Integer id){
Employee employee = employeeService.getEmp(id);
return employee;
}
@GetMapping("/updateEmployee")
public Employee update(Employee employee){
Employee emp = employeeService.updateEmp(employee);
return emp;
}
@GetMapping("/deleteEmployee")
public String deleteEmp(Integer id){
employeeService.deleteEmp(id);
return "success";
}
@GetMapping("/emp/{lastName}")
public Employee getEmployeeByLastName(@PathVariable("lastName") String lastName){
return employeeService.getEmployeeByLastName(lastName);
}
}
service層:
public Employee getEmp(Integer id){
System.out.println("查詢"+id+"員工");
Employee employee = employeeMapper.getEmpById(id);
Cache cache = cacheManager.getCache("emp");
cache.put("emp:"+id,employee);
return employee;
}
/**
* @CachePut:既調用方法,又更新緩存
* 修改了數據庫的數據,並同時更新緩存
* 運行機制:
* 1、先調用目標方法;
* 2、將目標方法的結果緩存起來
*/
@CachePut(/*value = "emp",*/key="#result.id")
public Employee updateEmp(Employee employee){
System.out.println("update:"+employee);
employeeMapper.updateEmp(employee);
return employee;
}
/**
* @CacheEvict:清除緩存
* allEntries=true清空這個緩存中的所有數據
* beforeInvocation=true代表清空緩存操作是在方法執行前就執行了,無論方法是否出現異常,緩存都會被清除
*/
@CacheEvict(/*value = "emp",*/key = "#id"/*,allEntries = true*/,beforeInvocation = true)
public void deleteEmp(Integer id){
System.out.println("deletEmp:"+id);
//employeeMapper.deleteEmpById(id);
int a = 10/0;
}
/**
* @Caching 定義複雜的緩存規則
*/
@Caching(
cacheable = {
@Cacheable(/*value = "emp",*/key = "#lastName")
},
put = {
@CachePut(/*value = "emp",*/key = "#result.id")
}
)
public Employee getEmployeeByLastName(String lastName){
System.out.println("getEmployeeByLastName:"+lastName);
return employeeMapper.getEmpByLastName(lastName);
}
}
好了,講解結束,小夥伴們點贊、收藏、評論,一鍵三連走起呀,下期見~