Redis的集成和簡(jiǎn)單使用

姓名:王玉剛? ? ? ?學(xué)號(hào):17021211232

【嵌牛導(dǎo)讀】:利用Mybatis-Plus這個(gè)第三方的ORM框架進(jìn)行數(shù)據(jù)庫(kù)訪問(wèn)故源,在實(shí)際工作中祭钉,在存儲(chǔ)一些非結(jié)構(gòu)化或者緩存一些臨時(shí)數(shù)據(jù)及熱點(diǎn)數(shù)據(jù)時(shí),一般上都會(huì)用上mongodb和redis進(jìn)行這方面的需求。所以這一章節(jié)準(zhǔn)備講下緩存數(shù)據(jù)庫(kù)Redis的集成威恼,同時(shí)會(huì)介紹下基于Redis和注解驅(qū)動(dòng)的Spring Cache的簡(jiǎn)單使用。

【嵌牛鼻子】:Redis? SpringBoot

【嵌牛提問(wèn)】:SpringBoot還有其他的相關(guān)軟件集成嗎?

【嵌牛正文】:SpringBoot的Redis集成

1.pom依賴(lài)

org.springframework.bootspring-boot-starter-data-redis

直接引入箫措,相關(guān)依賴(lài)會(huì)自動(dòng)加載的腹备,這就是springboot讓人愉悅之處呀。

2.application.properties配置加入redis相關(guān)配置

配置自動(dòng)加載類(lèi)為:org.springframework.boot.autoconfigure.data.redis.RedisProperties斤蔓,可在屬性文件中點(diǎn)擊某屬性快捷跳轉(zhuǎn)植酥。注意到其啟動(dòng)類(lèi)為org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration。這里就不介紹了弦牡,后面會(huì)寫(xiě)一篇關(guān)于Springboot自動(dòng)加載配置的文章友驮。

# REDIS (RedisProperties)# Redis數(shù)據(jù)庫(kù)索引(默認(rèn)為0)spring.redis.database=0# Redis服務(wù)器地址spring.redis.host=127.0.0.1# Redis服務(wù)器連接端口spring.redis.port=6379# Redis服務(wù)器連接密碼(默認(rèn)為空)spring.redis.password=# 連接池最大連接數(shù)(使用負(fù)值表示沒(méi)有限制)spring.redis.pool.max-active=8# 連接池最大阻塞等待時(shí)間(使用負(fù)值表示沒(méi)有限制)spring.redis.pool.max-wait=-1# 連接池中的最大空閑連接spring.redis.pool.max-idle=8# 連接池中的最小空閑連接spring.redis.pool.min-idle=0# 連接超時(shí)時(shí)間(毫秒)spring.redis.timeout=0

3.一般上通過(guò)以上兩步就可使用了,但工作中一般上是通過(guò)StringRedisTemplate(默認(rèn)采用string的序列化驾锰,保存key和值時(shí)都是通過(guò)此序列化策略)接口進(jìn)行操作卸留,所以這里直接配置了StringRedisTemplatebean類(lèi)。?

/** *? *@authoroKong * */@ConfigurationpublicclassRedisConfig{/**? ? *? 定義 StringRedisTemplate 稻据,指定序列化和反序列化的處理類(lèi)? ? *@paramfactory? ? *@return*/@BeanpublicRedisTemplateredisTemplate(RedisConnectionFactory factory){? ? ? ? StringRedisTemplate template =newStringRedisTemplate(factory);? ? ? ? Jackson2JsonRedisSerializer jackson2JsonRedisSerializer =newJackson2JsonRedisSerializer<>(? ? ? ? ? ? ? ? Object.class);? ? ? ? ObjectMapper om =newObjectMapper();? ? ? ? om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);? ? ? ? om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);? ? ? ? jackson2JsonRedisSerializer.setObjectMapper(om);//序列化 值時(shí)使用此序列化方法template.setValueSerializer(jackson2JsonRedisSerializer);? ? ? ? template.afterPropertiesSet();returntemplate;? ? }}

4.編寫(xiě)控制類(lèi)艾猜,測(cè)試集成是否生效。

@RestController@RequestMapping("/redis")@Api(tags ="redis 測(cè)試API")publicclassRedisController{@AutowiredStringRedisTemplate redisTemplate;@GetMapping("set/{key}/{value}")@ApiOperation(value="設(shè)置緩存")publicStringset(@PathVariable("key")String key,@PathVariable("value")String value){//注意這里的 key不能為null spring 內(nèi)部有檢驗(yàn)redisTemplate.opsForValue().set(key, value);returnkey +","+ value;}@GetMapping("get/{key}")@ApiOperation(value="根據(jù)key獲取緩存")publicStringget(@PathVariable("key")String key){return"key="+ key +",value="+ redisTemplate.opsForValue().get(key);}}

5.set值?

get值?

查看redis記錄:

至此捻悯,redis就集成好了匆赃。實(shí)際中可根據(jù)業(yè)務(wù)需要進(jìn)行相關(guān)操作,比如緩存session記錄今缚,緩存菜單列表等算柳。

Spring Cache 和 redis 使用。

Spring Cache是Spring框架提供的對(duì)緩存使用的抽象類(lèi)姓言,支持多種緩存瞬项,比如Redis、EHCache等何荚,集成很方便囱淋。同時(shí)提供了多種注解來(lái)簡(jiǎn)化緩存的使用,可對(duì)方法進(jìn)行緩存餐塘。

0.修改RedisConfig配置類(lèi)妥衣,加入注解@EnableCaching,同時(shí)設(shè)置CacheManager緩存管理類(lèi)戒傻,這里使用RedisCacheManager税手,其他的管理類(lèi)還有:SimpleCacheManager、ConcurrentMapCacheManager等需纳,默認(rèn)提供的在類(lèi)org.springframework.cache.support下芦倒,可自行查閱。

/** *? *@authoroKong * */@Configuration@EnableCachingpublicclassRedisConfig{/**? ? *? 定義 StringRedisTemplate 不翩,指定序列號(hào)和反序列化的處理類(lèi)? ? *@paramfactory? ? *@return*/@BeanpublicRedisTemplateredisTemplate(RedisConnectionFactory factory){? ? ? ? StringRedisTemplate template =newStringRedisTemplate(factory);? ? ? ? Jackson2JsonRedisSerializer jackson2JsonRedisSerializer =newJackson2JsonRedisSerializer<>(? ? ? ? ? ? ? ? Object.class);? ? ? ? ObjectMapper om =newObjectMapper();? ? ? ? om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);? ? ? ? om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);? ? ? ? jackson2JsonRedisSerializer.setObjectMapper(om);//序列化 值時(shí)使用此序列化方法template.setValueSerializer(jackson2JsonRedisSerializer);? ? ? ? template.afterPropertiesSet();returntemplate;? ? }@BeanpublicCacheManagercacheManager(RedisTemplate redisTemplate){? ? ? ? RedisCacheManager rcm =newRedisCacheManager(redisTemplate);//使用前綴rcm.setUsePrefix(true);//緩存分割符 默認(rèn)為 ":"http://? ? ? ? rcm.setCachePrefix(new DefaultRedisCachePrefix(":"));//設(shè)置緩存過(guò)期時(shí)間//rcm.setDefaultExpiration(60);//秒returnrcm;? ? }}

1.改造UserController控制層兵扬,引入@Cacheable等注解麻裳。

/** * 用戶控制層 簡(jiǎn)單演示增刪改查及分頁(yè) * 新增了swagger文檔內(nèi)容 2018-07-21 * 新增了@caching使用 2018-07-23 *@authoroKong * */@RestController@RequestMapping("/user")@Api(tags="用戶API")publicclassUserController{@AutowiredIUserService userService;@PostMapping("add")@ApiOperation(value="用戶新增")//正常業(yè)務(wù)時(shí), 需要在user類(lèi)里面進(jìn)行事務(wù)控制周霉,控制層一般不進(jìn)行業(yè)務(wù)控制的掂器。//@Transactional(rollbackFor = Exception.class)publicMapaddUser(@Valid @RequestBody UserReq userReq){? ? ? ? ? ? ? ? User user =newUser();? ? ? ? user.setCode(userReq.getCode());? ? ? ? user.setName(userReq.getName());//由于設(shè)置了主鍵策略 id可不用賦值 會(huì)自動(dòng)生成//user.setId(0L);userService.insert(user);? ? ? ? Map result =newHashMap();? ? ? ? result.put("respCode","01");? ? ? ? result.put("respMsg","新增成功");//事務(wù)測(cè)試//System.out.println(1/0);returnresult;? ? }@PostMapping("update")@ApiOperation(value="用戶修改")//更新時(shí) 直接刪除緩存 以保證下次獲取時(shí)先從數(shù)據(jù)庫(kù)中獲取最新數(shù)據(jù)@CacheEvict(value="OKONG", key="#userReq.id")publicMapupdateUser(@Valid @RequestBody UserReq userReq){if(userReq.getId() ==null||"".equals(userReq.getId())) {thrownewCommonException("0000","更新時(shí)ID不能為空");? ? ? ? }? ? ? ? User user =newUser();? ? ? ? user.setCode(userReq.getCode());? ? ? ? user.setName(userReq.getName());? ? ? ? user.setId(Long.parseLong(userReq.getId()));? ? ? ? ? ? ? ? userService.updateById(user);? ? ? ? Map result =newHashMap();? ? ? ? result.put("respCode","01");? ? ? ? result.put("respMsg","更新成功");returnresult;? ? }@GetMapping("/get/{id}")@ApiOperation(value="用戶查詢(xún)(ID)")@ApiImplicitParam(name="id",value="查詢(xún)ID",required=true)@Cacheable(value="OKONG",key="#id")publicMapgetUser(@PathVariable("id")String id){//查詢(xún)User user = userService.selectById(id);if(user ==null) {thrownewCommonException("0001","用戶ID:"+ id +",未找到");? ? ? ? }? ? ? ? UserResp resp = UserResp.builder()? ? ? ? ? ? ? ? .id(user.getId().toString())? ? ? ? ? ? ? ? .code(user.getCode())? ? ? ? ? ? ? ? .name(user.getName())? ? ? ? ? ? ? ? .status(user.getStatus())? ? ? ? ? ? ? ? .build();? ? ? ? Map result =newHashMap();? ? ? ? result.put("respCode","01");? ? ? ? result.put("respMsg","成功");? ? ? ? result.put("data", resp);returnresult;? ? }@GetMapping("/page")@ApiOperation(value="用戶查詢(xún)(分頁(yè))")publicMappageUser(intcurrent,intsize){//分頁(yè)P(yáng)age page =newPage<>(current, size);? ? ? ? Map result =newHashMap();? ? ? ? result.put("respCode","01");? ? ? ? result.put("respMsg","成功");? ? ? ? result.put("data", userService.selectPage(page));returnresult;? ? }? ? ? ? }

2.利用Swagger控制頁(yè)面俱箱,新增一個(gè)用戶国瓮,然后獲取用戶,會(huì)發(fā)現(xiàn)緩存里已經(jīng)有此id的用戶數(shù)據(jù)了狞谱。

redis查看:?

再次獲取乃摹,會(huì)發(fā)現(xiàn)這次沒(méi)有直接訪問(wèn)數(shù)據(jù)庫(kù)了,而是直接從緩存讀取跟衅。大家可在觀察下控制臺(tái)的輸出情況(可先清空控制臺(tái)孵睬,然后在請(qǐng)求)。

?此時(shí)控制臺(tái)無(wú)任何輸出伶跷,但前端已經(jīng)獲取到值了掰读。

關(guān)于SpringCache 注解的簡(jiǎn)單介紹

@Cacheable:標(biāo)記在一個(gè)方法上,也可以標(biāo)記在一個(gè)類(lèi)上叭莫。主要是緩存標(biāo)注對(duì)象的返回結(jié)果蹈集,標(biāo)注在方法上緩存該方法的返回值,標(biāo)注在類(lèi)上雇初,緩存該類(lèi)所有的方法返回值拢肆。 參數(shù): value緩存名、 key緩存鍵值靖诗、 condition滿足緩存條件郭怪、unless否決緩存條件

@CacheEvict:從緩存中移除相應(yīng)數(shù)據(jù)。

@CachePut:方法支持緩存功能刊橘。與@Cacheable不同的是使用@CachePut標(biāo)注的方法在執(zhí)行前不會(huì)去檢查緩存中是否存在之前執(zhí)行過(guò)的結(jié)果鄙才,而是每次都會(huì)執(zhí)行該方法,并將執(zhí)行結(jié)果以鍵值對(duì)的形式存入指定的緩存中促绵。

@Caching:多個(gè)Cache注解使用,比如新增用戶時(shí)咒循,刪除用戶屬性等需要?jiǎng)h除或者更新多個(gè)緩存時(shí),集合以上三個(gè)注解绞愚。

SpEL上下文數(shù)據(jù)

Spring Cache提供了一些供我們使用的SpEL上下文數(shù)據(jù),下表直接摘自互聯(lián)網(wǎng)

名稱(chēng)位置描述示例

methodNameroot對(duì)象當(dāng)前被調(diào)用的方法名root.methodName

methodroot對(duì)象當(dāng)前被調(diào)用的方法root.method.name

targetroot對(duì)象當(dāng)前被調(diào)用的目標(biāo)對(duì)象root.target

targetClassroot對(duì)象當(dāng)前被調(diào)用的目標(biāo)對(duì)象類(lèi)root.targetClass

argsroot對(duì)象當(dāng)前被調(diào)用的方法的參數(shù)列表root.args[0]

cachesroot對(duì)象當(dāng)前方法調(diào)用使用的緩存列表(如@Cacheable(value={“cache1”, “cache2”}))颖医,則有兩個(gè)cacheroot.caches[0].name

argument name執(zhí)行上下文當(dāng)前被調(diào)用的方法的參數(shù)位衩,如findById(Long id),我們可以通過(guò)#id拿到參數(shù)user.id

result執(zhí)行上下文方法執(zhí)行后的返回值(僅當(dāng)方法執(zhí)行之后的判斷有效熔萧,如‘unless’糖驴,’cache evict’的beforeInvocation=false)result

@CacheEvict(value ="user", key ="#user.id", condition ="#root.target.canCache() and #root.caches[0].get(#user.id).get().username ne #user.username", beforeInvocation =true)publicvoidconditionUpdate(User user)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末僚祷,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子贮缕,更是在濱河造成了極大的恐慌辙谜,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,627評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件感昼,死亡現(xiàn)場(chǎng)離奇詭異装哆,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)定嗓,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,180評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)蜕琴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人宵溅,你說(shuō)我怎么就攤上這事凌简。” “怎么了恃逻?”我有些...
    開(kāi)封第一講書(shū)人閱讀 169,346評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵雏搂,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我寇损,道長(zhǎng)凸郑,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 60,097評(píng)論 1 300
  • 正文 為了忘掉前任润绵,我火速辦了婚禮线椰,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘尘盼。我一直安慰自己憨愉,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,100評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布卿捎。 她就那樣靜靜地躺著配紫,像睡著了一般。 火紅的嫁衣襯著肌膚如雪午阵。 梳的紋絲不亂的頭發(fā)上躺孝,一...
    開(kāi)封第一講書(shū)人閱讀 52,696評(píng)論 1 312
  • 那天,我揣著相機(jī)與錄音底桂,去河邊找鬼植袍。 笑死,一個(gè)胖子當(dāng)著我的面吹牛籽懦,可吹牛的內(nèi)容都是我干的于个。 我是一名探鬼主播,決...
    沈念sama閱讀 41,165評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼暮顺,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼厅篓!你這毒婦竟也來(lái)了秀存?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 40,108評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤羽氮,失蹤者是張志新(化名)和其女友劉穎或链,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體档押,經(jīng)...
    沈念sama閱讀 46,646評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡澳盐,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,709評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了汇荐。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片洞就。...
    茶點(diǎn)故事閱讀 40,861評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖掀淘,靈堂內(nèi)的尸體忽然破棺而出旬蟋,到底是詐尸還是另有隱情,我是刑警寧澤革娄,帶...
    沈念sama閱讀 36,527評(píng)論 5 351
  • 正文 年R本政府宣布倾贰,位于F島的核電站,受9級(jí)特大地震影響拦惋,放射性物質(zhì)發(fā)生泄漏匆浙。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,196評(píng)論 3 336
  • 文/蒙蒙 一厕妖、第九天 我趴在偏房一處隱蔽的房頂上張望首尼。 院中可真熱鬧,春花似錦言秸、人聲如沸软能。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,698評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)查排。三九已至,卻和暖如春抄沮,著一層夾襖步出監(jiān)牢的瞬間跋核,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,804評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工叛买, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留砂代,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,287評(píng)論 3 379
  • 正文 我出身青樓率挣,卻偏偏與公主長(zhǎng)得像泊藕,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,860評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理娃圆,服務(wù)發(fā)現(xiàn),斷路器蛾茉,智...
    卡卡羅2017閱讀 134,715評(píng)論 18 139
  • 放棄一個(gè)人讼呢,從來(lái)都不是一瞬間的事,當(dāng)全部的愛(ài)慕和關(guān)心一點(diǎn)點(diǎn)被消磨干凈谦炬,我也漸漸的攢夠了失望和無(wú)奈悦屏。當(dāng)初那么喜歡,現(xiàn)...
    灰太狼愛(ài)美羊羊1108閱讀 216評(píng)論 0 0
  • 1.減少購(gòu)買(mǎi)欲键思,不買(mǎi)不需要之物 2.減少使用社交網(wǎng)絡(luò) 3.定期整理房間 4.作息規(guī)律 5.穿著簡(jiǎn)潔础爬,不花哨
    簡(jiǎn)單215閱讀 251評(píng)論 0 0
  • 這是個(gè)人氣還不錯(cuò)的幼兒畫(huà)畫(huà)培訓(xùn)機(jī)構(gòu),離我家挺遠(yuǎn)吼鳞,我和老公考察了兩個(gè)類(lèi)似的培訓(xùn)機(jī)構(gòu)之后選擇了這家看蚜,怎么說(shuō)呢,對(duì)于我和...
    山下一支竹閱讀 126評(píng)論 0 0