cacheput注解 用法_以注解的方式使用redis缓存得用法@CachePut , @CacheEvict, @Cacheable...
第一步:在啟動類加注解@EnableCaching
@SpringBootApplication
@EnableCaching
//@MapperScan(basePackages = "com.imooc.dataobject.mapper")
public class SellApplication {
public static void main(String[] args) {
SpringApplication.run(SellApplication.class, args);
}
}
第二部:在相應的需要緩存的類里面加個注解,測試一下
然后果然不出所料,一大堆錯誤和坑,一起來看看,原來是Serializable的錯誤
java.lang.IllegalArgumentException: DefaultSerializer requires a Serializable payload but received an object of type [com.imooc.VO.ResultVO]
Hibernate: select productcat0_.category_id as category1_2_, productcat0_.category_name as category2_2_, productcat0_.category_type as category3_2_, productcat0_.create_time as create_t4_2_, productcat0_.update_time as update_t5_2_ from product_category productcat0_
arializationRedisSerializer.java:91)
at org.springframework.data.redis.cache.RedisCache$CacheValueAccessor.convertToBytesIfNecessary(RedisCache.java:471)
解決錯誤的辦法就是加序列化public class ResultVO implements Serializable
可以給每一個都這樣操作
@Data
public class ResultVO implements Serializable {
//自己瞎寫了一個
private static final long serialVersionUID = 222343234234L;
//resultVO 類自己的屬性
private Integer code;
private String msg;
//保存具體內容,是個對象,泛型實現。
private T data;
}
然后再類里面生成ID,需要用到一下這個插件,在idea里下載,重啟即可
然后運行,可以看到一件成功顯示數據,再打開Redis客戶端,可以看到有product的一條數據,
然后你不斷的刷新,都不會再進入那個方法,因為直接從緩存中拿到這個序列化存儲的對象,
但是這里有一個很嚴重的問題,你把數據庫的信息改了,然后刷新頁面,還是原來的數據,這就是因為緩存的原因,所以我們給save更新的方法也要加個更新的處理, 接口方式。如圖。
@PostMapping("/save")
@CachePut(cacheNames = "product", key = "123")
public ModelAndView save(@Valid ProductForm productForm,
BindingResult bindingResult,
Map map){
// 1 先驗證提交過來的表單有無錯誤信息 -- 有 -- 跳轉錯誤頁面
if(bindingResult.hasErrors()){
map.put("msg", bindingResult.getFieldError().getDefaultMessage());
map.put("url", "/sell/seller/product/list");
return new ModelAndView("common/error", map);
}
ProductInfo productInfo = new ProductInfo();
// if(productForm.getProductId() != null){
// productForm.setProductId(KeyUtil.genUniqueKey());
// }
// 2 沒有錯誤, 拷貝表單信息 為 商品信息格式,
// 為了完整 -- 提前查好, 弄好默認值
// 然后存儲 -- 調用service 層方法 -- 出錯處理
try{
/** 這里必須判斷 是新增 還是 修改, 有幾個特定的屬性需要單獨賦值處理
* 如果productId為空, 說明是新增 -- 不是新增:查找。 是新增:設置ID。
* ************** 新增和增加的 關鍵點核心 *****************
*/
if(!StringUtils.isEmpty(productForm.getProductId())){
productInfo = productInfoService.findOne(productForm.getProductId());
}else{
productForm.setProductId(KeyUtil.genUniqueKey());
}
BeanUtils.copyProperties(productForm, productInfo);
productInfoService.save(productInfo);
}catch (SellException e){
map.put("msg", e.getMessage());
map.put("url", "/sell/seller/product/list");
return new ModelAndView("common/error", map);
}
map.put("msg", ResultEnum.SUCCESS.getMessage());
map.put("url", "/sell/seller/product/list");
return new ModelAndView("common/success", map);
}
但是這樣會報錯,因為更新時候返回的是ModelandView對象, 而前面我們保存的是resultVO,對象不同,顯然報錯,所以改用另一種方法, 用一種注解代替
// @CachePut(cacheNames = "product", key = "123")
@CacheEvict(cacheNames = "product", key = "123")
@CacheEvict(cacheNames = "product", key = "123")就代表來的時候執行這個方法,執行完之后把結果從Redis中驅趕出去,也就是刪除,當再次訪問查詢時候,Redis中沒有這個數據,再次數據庫查詢 -- 從而達到更新的目的。
以上講的是基本用法,Redis的知識很豐富,持續關注
cacheNames = "product", key = "123",
其實這兩個值應該是動態變化的,例如這樣,
@CachePut(cacheNames = "product", key = "#productId")
public ProductInfo findOne(String productId)
這個叫做skel表達式
@Override
@CachePut(cacheNames = "product", key = "#productId")
public ProductInfo findOne(String productId) {
return repository.findOne(productId);
}
注意點:
@CacheConfig(cacheNames = "product")
1.?cacheNames = "product", key = "123",這兩個必須寫,
@CachePut(cacheNames = "product", key = "#productId",
condition="#productId.length() > 3" ,
unless = "#result.getCode() != 0")
這些都是他的擴展用法,具體不在講述,我只體現框架概念。
總結
以上是生活随笔為你收集整理的cacheput注解 用法_以注解的方式使用redis缓存得用法@CachePut , @CacheEvict, @Cacheable...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【ceph】Ceph 存储中 PGMap
- 下一篇: 连接真机开发安卓(Android)移动a