最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring Boot基礎(chǔ)學(xué)習(xí)之Mybatis操作中使用Redis做緩存詳解

 更新時(shí)間:2018年11月07日 09:46:21   作者:小崔的筆記本  
這篇文章主要給大家介紹了關(guān)于Spring Boot基礎(chǔ)學(xué)習(xí)之Mybatis操作中使用Redis做緩存的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用spring boot具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起看看吧

前言

這篇博客學(xué)習(xí)下Mybatis操作中使用Redis做緩存。這里其實(shí)主要學(xué)習(xí)幾個(gè)注解:@CachePut、@Cacheable、@CacheEvict、@CacheConfig。

下面話不多說了,來一起看看詳細(xì)的介紹吧

一、基礎(chǔ)知識

@Cacheable

@Cacheable 的作用 主要針對方法配置,能夠根據(jù)方法的請求參數(shù)對其結(jié)果進(jìn)行緩存

參數(shù) 解釋 example
value 緩存的名稱,在 spring 配置文件中定義,必須指定至少一個(gè) 例如:
@Cacheable(value=”mycache”)
@Cacheable(value={”cache1”,”cache2”}
key 緩存的 key,可以為空,如果指定要按照 SpEL 表達(dá)式編寫,如果不指定,則缺省按照方法的所有參數(shù)進(jìn)行組合 @Cacheable(value=”testcache”,key=”#userName”)
condition 緩存的條件,可以為空,使用 SpEL 編寫,返回 true 或者 false,只有為 true 才進(jìn)行緩存 @Cacheable(value=”testcache”,condition=”#userName.length()>2”)

 @CachePut

@CachePut 的作用 主要針對方法配置,能夠根據(jù)方法的返回值對其結(jié)果進(jìn)行緩存,和 @Cacheable 不同的是,它每次都會觸發(fā)真實(shí)方法的調(diào)用,在其他地方寫的是根據(jù)方法的請求參數(shù)對其結(jié)果進(jìn)行緩存,實(shí)際是按方法返回值進(jìn)行緩存的,這里我就遇到了一個(gè)坑,我開始的時(shí)候是在Mybatis的Mapper層進(jìn)行緩存的,如下面的代碼。但是緩存到Redis的是Null值,今天看了一博友的博客,交流了一下,才知道它緩存的是方法的返回值,如果把下面update的返回值該為int,在redis中保存的是int類型,報(bào)的錯(cuò)誤是int無法轉(zhuǎn)換成User對象。

 @CachePut(value="user",key = "#p0.id")
 @Update({"UPDATE user SET name=#{name},age=#{age} WHERE id =#{id}"})
 void update(User user);

參數(shù) 解釋 example
value 緩存的名稱,在 spring 配置文件中定義,必須指定至少一個(gè) @CachePut(value=”my cache”)
key 緩存的 key,可以為空,如果指定要按照 SpEL 表達(dá)式編寫,如果不指定,則缺省按照方法的所有參數(shù)進(jìn)行組合 @CachePut(value=”testcache”,key=”#userName”)
condition 緩存的條件,可以為空,使用 SpEL 編寫,返回 true 或者 false,只有為 true 才進(jìn)行緩存 @CachePut(value=”testcache”,condition=”#userName.length()>2”)

 @CachEvict

 @CachEvict 的作用 主要針對方法配置,能夠根據(jù)一定的條件對緩存進(jìn)行清空

參數(shù) 解釋 example
value 緩存的名稱,在 spring 配置文件中定義,必須指定至少一個(gè) @CacheEvict(value=”my cache”)
key 緩存的 key,可以為空,如果指定要按照 SpEL 表達(dá)式編寫,如果不指定,則缺省按照方法的所有參數(shù)進(jìn)行組合 @CacheEvict(value=”testcache”,key=”#userName”)
condition 緩存的條件,可以為空,使用 SpEL 編寫,返回 true 或者 false,只有為 true 才進(jìn)行緩存 @CacheEvict(value=”testcache”,condition=”#userName.length()>2”)
allEntries 是否清空所有緩存內(nèi)容,缺省為 false,如果指定為 true,則方法調(diào)用后將立即清空所有緩存 @CachEvict(value=”testcache”,allEntries=true)
beforeInvocation 是否在方法執(zhí)行前就清空,缺省為 false,如果指定為 true,則在方法還沒有執(zhí)行的時(shí)候就清空緩存,缺省情況下,如果方法執(zhí)行拋出異常,則不會清空緩存 @CachEvict(value=”testcache”,beforeInvocation=true)

@CacheConfig

所有的@Cacheable()里面都有一個(gè)value=“xxx”的屬性,這顯然如果方法多了,寫起來也是挺累的,如果可以一次性聲明完 那就省事了,有了@CacheConfig這個(gè)配置,@CacheConfig is a class-level annotation that allows to share the cache names,如果你在你的方法寫別的名字,那么依然以方法的名字為準(zhǔn)。

二、實(shí)例

還是在上一博客demo的基礎(chǔ)上進(jìn)行修改,原本是在Mybatis的Mapper層上增加cache注解,但由于update返回值為void,所以這里又增加了一services層,mapper層算是DAO層。這里使用了@CacheConfig注解指定類級別的value屬性,如果在方法上定義就以方法為主,就近原則。

package com.example.services;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import com.example.model.User;
import com.example.write.mapper.WriteUserMapper;


@Service
@CacheConfig(cacheNames="user")
public class UserServices {
 
 @Autowired 
 private WriteUserMapper writeUserMapper;

 public List<User> getAll()
 {
  return writeUserMapper.getAll();
 }
 
 @Cacheable(key = "#p0")
 public User getOne(String id)
 {
  return writeUserMapper.getOne(id);
 }
 
 public void insert(User user)
 {
  writeUserMapper.insert(user);
 }
 
 @CachePut(value="user",key = "#p0.id")
 public User update(User user)
 {
  writeUserMapper.update(user);
  return user;
 }
 
 @CacheEvict(value="user",key ="#p0",allEntries=true)
 public void delete(String id)
 {
  writeUserMapper.delete(id);
 }
 
}

UserController

package com.example.demo;

import java.io.Serializable;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import com.example.model.User;
import com.example.model.UserSexEnum;
import com.example.read.mapper.ReadUserMapper;
import com.example.services.UserServices;
import com.example.write.mapper.WriteUserMapper;

import io.lettuce.core.dynamic.annotation.Param;

@Controller
@RequestMapping("/user")
public class UserController {
 
 @Autowired
 private WriteUserMapper userMapperWrite;
 
 @Autowired
 private ReadUserMapper userMapperRead;
 
 @Autowired
 private StringRedisTemplate stringRedisTemplate;

 @Autowired
 private RedisTemplate<String, Serializable> redisCacheTemplate;
 
 @Autowired
 private UserServices userServices;
 
 @RequestMapping(value = "/alluser.do",method = RequestMethod.GET)
 public String getallusers(Model model) {
  List<User> users=userServices.getAll();
  model.addAttribute("users", users);
//  stringRedisTemplate.opsForValue().set("keytest", "cuiyw");
//  final String keytest = stringRedisTemplate.opsForValue().get("keytest");
//  model.addAttribute("keytest", keytest);
//  String key = "1857XXXX040";
//  redisCacheTemplate.opsForValue().set(key, new User(key, "cuiyw", 18, UserSexEnum.MAN));
//  // TODO 對應(yīng) String(字符串)
//  final User user = (User) redisCacheTemplate.opsForValue().get(key);
//  model.addAttribute("user", user);
  return "userlist";
 }
 @RequestMapping(value = "/insert.do",method = RequestMethod.GET)
 public String adduser(Model model) {
  User user=new User();
  user.setName("cuiyw");
  user.setAge(27); 
  userServices.insert(user);
//  List<User> users=userMapperWrite.getAll();
//  model.addAttribute("users", users);
  return "forward:/user/alluser.do"; 

 }
 @RequestMapping(value = "/getuserbyid.do/{id}",method = RequestMethod.GET)
 public ModelAndView GetUserById(@PathVariable("id") String id) {
  System.out.println(id);
  User user=userServices.getOne(id);
  System.out.println(user.toString());
  ModelAndView modelAndView = new ModelAndView("userlist"); 
  

  modelAndView.addObject("user", user);
  return modelAndView; 

 }
 @RequestMapping(value = "/deleteuserbyid.do/{id}",method = RequestMethod.GET)
 public String DeleteUserById(@PathVariable("id") String id) {
  userServices.delete(id);
  return "forward:/user/alluser.do"; 
  

 }
 @RequestMapping(value = "/updateuserbyid.do/{id}",method = RequestMethod.GET)
 public String UpdateUserByid(@PathVariable("id") String id) {
  User user=userServices.getOne(id);
  System.out.println(user.toString());
  user.setAge(28);
  System.out.println(user.toString());
  userServices.update(user);
   System.out.println(user.toString());
  return "forward:/user/alluser.do"; 

  
 }
}

這里先輸入http://localhost:8080/user/getuserbyid.do/17通過getOne()方法在redis中緩存一個(gè)user。通過redis-cli可以看到user::17已在redis中。

 然后通過update()方法輸入http://localhost:8080/user/updateuserbyid.do/17修改user,此時(shí)年齡改為了28,數(shù)據(jù)庫的值也會變了。然后多次使用http://localhost:8080/user/updateuserbyid.do/17這個(gè)url刷新瀏覽器,此時(shí)是不會報(bào)錯(cuò)的,如果是在mapper中使用@Cacheput時(shí)由于保存的是null就會導(dǎo)致報(bào)錯(cuò)。

最后通過delete()方法輸入http://localhost:8080/user/deleteuserbyid.do/17刪除redis和數(shù)據(jù)庫中的user對象.

至此,基本把這4個(gè)注解大致了解了一下,這里還有一個(gè)地方需要補(bǔ)充,就是如果按照上面運(yùn)行還是不行的,它依然找不到UserServices,在UserController中找不到這個(gè)類,還需要在main方法上面@ComponentScan注解加上掃描com.example.services。

@ComponentScan(basePackages={"com.example.config","com.example.demo","com.example.services"})

最后來一碗雞湯,記錄下今天看抖音聽到的一句話,還挺有道理。

為什么大多數(shù)人寧愿吃生活的苦,而不愿意吃學(xué)習(xí)的苦?因?yàn)閷W(xué)習(xí)的苦需要自己主動去吃,而生活的苦你躺著它就來了。

總結(jié):

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。

相關(guān)文章

  • Mybatis-plus4條件構(gòu)造器使用方式

    Mybatis-plus4條件構(gòu)造器使用方式

    這篇文章主要介紹了Mybatis-plus4條件構(gòu)造器使用方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-02-02
  • IntelliJ IDEA 2020.3 重大特性(新功能一覽)

    IntelliJ IDEA 2020.3 重大特性(新功能一覽)

    這篇文章主要介紹了IntelliJ IDEA 2020.3 重大特性(新功能一覽),本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-12-12
  • jar包和war包區(qū)別解析

    jar包和war包區(qū)別解析

    jar是java普通項(xiàng)目打包,通常是開發(fā)時(shí)要引用通用類,打成jar包便于存放管理,war是java web項(xiàng)目打包,web網(wǎng)站完成后,打成war包部署到服務(wù)器,目的是為了節(jié)省資源,提供效率,這篇文章主要介紹了jar包和war包區(qū)別及理解,需要的朋友可以參考下
    2023-07-07
  • Java實(shí)現(xiàn)發(fā)送郵件功能時(shí)碰到的坑

    Java實(shí)現(xiàn)發(fā)送郵件功能時(shí)碰到的坑

    之前用163郵箱發(fā)郵件時(shí)明明是成功的,但是使用中國移動自己的郵箱時(shí),無論如何在linux服務(wù)器中都發(fā)送不成功。下面小編給大家說下我是怎么解決的,一起看下吧
    2016-06-06
  • java使用三層架構(gòu)實(shí)現(xiàn)電影購票系統(tǒng)

    java使用三層架構(gòu)實(shí)現(xiàn)電影購票系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了java使用三層架構(gòu)實(shí)現(xiàn)電影購票系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-01-01
  • SpringSecurity?表單登錄的實(shí)現(xiàn)

    SpringSecurity?表單登錄的實(shí)現(xiàn)

    本文主要介紹了SpringSecurity?表單登錄的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • java多線程數(shù)據(jù)分頁處理實(shí)例講解

    java多線程數(shù)據(jù)分頁處理實(shí)例講解

    在本篇內(nèi)容里小編給大家分享了一篇關(guān)于java多線程數(shù)據(jù)分頁處理實(shí)例講解內(nèi)容,有興趣的朋友們可以學(xué)習(xí)下。
    2021-01-01
  • java利用DFA算法實(shí)現(xiàn)敏感詞過濾功能

    java利用DFA算法實(shí)現(xiàn)敏感詞過濾功能

    在最近的開發(fā)中遇到了敏感詞過濾,便去網(wǎng)上查閱了很多敏感詞過濾的資料,在這里也和大家分享一下自己的理解。下面這篇文章主要給大家介紹了關(guān)于java利用DFA算法實(shí)現(xiàn)敏感詞過濾功能的相關(guān)資料,需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-06-06
  • java基于jdbc連接mysql數(shù)據(jù)庫功能實(shí)例詳解

    java基于jdbc連接mysql數(shù)據(jù)庫功能實(shí)例詳解

    這篇文章主要介紹了java基于jdbc連接mysql數(shù)據(jù)庫功能,結(jié)合實(shí)例形式詳細(xì)分析了jdbc連接mysql數(shù)據(jù)庫的原理、步驟、實(shí)現(xiàn)方法及相關(guān)操作技巧,需要的朋友可以參考下
    2017-10-10
  • Java如何簡單快速入門JWT(token生成與驗(yàn)證)

    Java如何簡單快速入門JWT(token生成與驗(yàn)證)

    這篇文章主要給大家介紹了關(guān)于Java如何簡單快速入門JWT(token生成與驗(yàn)證)的相關(guān)資料,JWT是一個(gè)加密的字符串,JWT傳輸?shù)男畔⒔?jīng)過了數(shù)字簽名,因此傳輸?shù)男畔⒖梢员或?yàn)證和信任,需要的朋友可以參考下
    2023-12-12

最新評論

瑞安市| 缙云县| 邻水| 瓮安县| 牡丹江市| 武清区| 富蕴县| 玉龙| 广平县| 桃园县| 子洲县| 青浦区| 桐乡市| 昌乐县| 高雄县| 武威市| 台江县| 牙克石市| 开原市| 赫章县| 揭西县| 潜山县| 龙里县| 凉城县| 昌宁县| 喀喇沁旗| 上栗县| 宜兴市| 平昌县| 枣庄市| 临沂市| 梧州市| 慈溪市| 隆安县| 德令哈市| 永吉县| 静海县| 海原县| 冷水江市| 肥西县| 东丽区|