Spring Boot 和 快取的使用(Redis)
阿新 • • 發佈:2021-07-18
Spring Boot 和 快取的使用(Redis)
JSR107的規範
Java Caching定義了5個核心介面,分別是CacheingProvider,CacheManager,Cache,Entry和Expiry
- CachingProvider定義建立、配置、獲取、管理、和控制多個CacheManager。一個應用可以在執行期間訪問多個CachingProvider
- CacheManage定義了建立、配置、獲取、管理和控制多個惟一命名的Cache,這些Cache存在CacheManager的上下文中。一個CacheManage僅被一個CachheProvider所擁有
- Cache是一個類似Map的資料結構並臨時儲存以key為索引的值。一個Cache僅被一個CacheManager所擁有
- Entry是一個儲存在Cache中的key—value對
- Enpiry是每一個儲存在Cache中的條目有一個定義的有效期。一旦超過這個歌時間,條目為過期狀態。一旦過期,條目將不可訪問、更新、刪除。儲存有效期可以通過ExpiryPolicy設定
新增依賴
<dependency>
<groupId>javax.cache</groupId>
<artifactId>cache-api</artifactId>
</dependency>
spring 快取抽象
常用的快取註解
引入依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>javax.cache</groupId> <artifactId>cache-api</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-redis</artifactId> </dependency>
- @EnableCaching 開啟基於註解的快取
@ComponentScan({"com.zzy.demo.dao"})
@SpringBootApplication
@EnableCaching//開啟快取
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
-
Cache 快取介面,定義快取操作。實現有:RedisCache、EhCacheCache等
-
CacheManager 快取管理器,管理各種快取(Cache)元件
-
@Cacheable 主要爭對方法配置,能夠根據方法的請求引數對其結果進行快取
-
/** * @Cacheable將方法的執行結果進行快取,以後再要相同的資料,直接從快取中獲取,不要呼叫方法 * 屬性: * cacheNames/value 指定快取元件的名字 也就是使用一張表用來儲存特定的 資料 * key 快取資料使用的key 可以用它來指定 預設是方法引數的值 因為Cache是以map的資料結構來儲存的所以要指定key值 形參-方法的返回值 * keyGenerator key的預設生成器 可以自己指定key的生成器 * cacheManager 指定快取管理器 * condition 指定符和條件的情況下才進行快取 * unless 否定快取 當unless指定的條件為 true 方法的返回值就不會被快取 * sync 是否使用非同步模式 * @return */ @Override @Cacheable(cacheNames = "book" ,key="#id",keyGenerator = "myKeyGenerator")//指定自定義的key生成器 public List<Book> selectBook() { List<Book> bookList = bookMapper.selectByExample(bookExample); return bookList; } }
//自己指定key值生成器 @Configuration public class MyConfiguration extends WebMvcAutoConfiguration { @Bean("myKeyGenerator") public KeyGenerator myKeyGenerator(){ return new KeyGenerator() { @Override public Object generate(Object o, Method method, Object... objects) { int i = 0; return method.getName()+"zzy"+i++; } }; } }
-
@CacheEvict 清空快取 快取清除
/**
* value 指定表
* key 指定刪除的key鍵值對
* allEntries 是否刪除快取中的所有資料 預設是false 不刪除
* beforeInvocation = false 指定快取的清除是否在方法之前清除 預設在方法之後執行清除 可以防止異常的丟擲 事務
* @param id
* @return
*/
@CacheEvict(value = "book",key = "#id")
public Integer delBook(Integer id){
Integer i = bookMapper.deleteByPrimaryKey(id);
return i;
}
- @CachePut 保證方法被呼叫 又希望結果被快取 即呼叫方法 又更新快取 同步更新快取
/**
* @Cache 和 @Cacheable 前者是先呼叫目標方法 再將目標方法的結果返回回來
* 注意: @Cache 方法會自動更新資料庫和快取庫中的資料 但是要注意的是 map資料結構的特性是key值覆蓋 所以它們的key值要是一樣的 要專門指定key的值和存入時的key值相等
注意 關於#result的取值 @Cacheable 註解的返回值是在方法執行之前的 而 @CachePut 的返回值是在方法執行之後的
* @param book
* @return
*/
@CachePut(value = "book",key = "#Book.id")//key="#result.id"
public Integer selectBook(Book book) {
Integer bookList = bookMapper.updateByPrimaryKey(book);
return bookList;
}
}
- @Caching 混合註解 高階 可以一次快取多個key值查詢
@Caching(
cacheable = {
@Cacheable(value = "book",key = "id")
},
put = {
@CachePut(value = "book" , key = "name"),
@CachePut(value = "book",key = "wirte")
}
)
public Book select(Integer id){
Book book = bookMapper.selectByPrimaryKey(id);
return book;
}
- @CacheConfig 抽取出公共的部分 比如 Cache元件的表 在方法中就不需要再寫了
@CacheConfig(cacheNames = "book")
public class BookServiceImpl implements BookService {
- keyGenerator 快取資料是key的 生成策略
- serialize 快取資料時value序列化策略
搭建Redis環境
Redis的安裝(docker):
- 下載相關映象 docker pull registry.docker-cn.com/library/Redis 使用中國映象下載
- 啟動容器
docker run -d -p 6379:6379 --name myredis redis
RedisTemplate 和 StringRedisTemplate 的使用 序列化的更改
引入Redis的starter
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-redis</artifactId>
</dependency>
配置redis
spring:
redis:
host: 192.168.11.xxx
一但redis成功引入 springboot自動配置起效 會幫助我產生兩個bean物件 StringRedisTemplate 和 RedisTemplate 物件用來簡化操作redis的
StringRedisTemplate:專門操作字串
RedsiTemplate:專門操作物件
設定自定義序列化器 更改預設的JdkSerializationRedisSerializer 序列化器 這樣傳出的值就是json了
修改RedisCacheManager
@Bean
public RedisTemplate<Object,Object> redisTemplate(){
RedisTemplate<Object,Object> template = new RedisTemplate<>();
Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
template.setDefaultSerializer(serializer);
return template;
}
@Bean
public RedisCacheManager redisCacheManager(RedisConnectionFactory redisConnectionFactory){
RedisCacheWriter redisCacheWriter = RedisCacheWriter.lockingRedisCacheWriter(redisConnectionFactory);
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig().serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()));
RedisCacheManager redisCacheManager = new RedisCacheManager(redisCacheWriter,redisCacheConfiguration);
return redisCacheManager;
}