Redis實戰(zhàn)(2)-數(shù)據(jù)結(jié)構(gòu)之字符串String實戰(zhàn)之存儲對象
作者:
修羅debug
版權(quán)聲明:本文為博主原創(chuàng)文章,遵循 CC 4.0 by-sa 版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接和本聲明。
摘要:在Redis眾多數(shù)據(jù)結(jié)構(gòu)當中,字符串String可以說是其中比較常見、應(yīng)用比較頻繁的一種了,本文我們將介紹數(shù)據(jù)類型~字符串String 在命令行的簡單使用及其在實際業(yè)務(wù)場景中的應(yīng)用與代碼實戰(zhàn),其中應(yīng)用場景為“存儲前端門戶網(wǎng)站的商品詳情信息”,從而減少數(shù)據(jù)庫DB的訪問頻率,提高接口的響應(yīng)速率!
內(nèi)容:緩存中間件Redis擁有多種豐富的數(shù)據(jù)結(jié)構(gòu),字符串String就是其中比較常見而且應(yīng)用相當廣泛的一種,下面我們將基于前文整合搭建的SpringBoot2.0+Redis的項目為奠基,從兩個方面進行介紹,即簡單的命令行、實際的應(yīng)用場景+代碼實戰(zhàn)!
(一)Redis命令行界面實操“數(shù)據(jù)類型String”
(1)由于Debug本地機子是windows系統(tǒng),故而為了可以在本地windows操作系統(tǒng)的機子使用Redis命令行,我們需要前往github下載一個windows版的redis綠色安裝工具包(如果是mac或者linux,則直接跳過此步驟),為了方便大家下載,我就直接提供地址給大家下載了(鏈接:https://pan.baidu.com/s/1o30jZZ9Rb5ZzR2iulQF9JA 提取碼:isj0)
下載完成之后,解壓到?jīng)]有中文名稱的磁盤目錄下,如下圖所示:
其中,最主要的文件當屬redis-server.exe、redis-cli.exe以及另外兩個用于數(shù)據(jù)持久化的rdb和aof文件,雙擊redis-server.exe,成功出現(xiàn)如下的界面即代表redis已經(jīng)成功在你本地運行起來了:
(2)下面,我們寫兩個簡單的命令(即如何往Redis存入一個Key,以及如何從Redis中獲取該Key對應(yīng)的值),簡單的感受一下字符串String在Redis命令行界面下的操作,如下圖所示:
是不是感覺很簡單???哈哈,本來就是如此!除此之外,還可以在RedisDesktopManager工具查看該Key的具體值!下面我進入重頭戲,即如何將Redis的這些特性應(yīng)用到實際的項目、實際的業(yè)務(wù)場景中去呢!
(二)String典型應(yīng)用場景代碼實戰(zhàn)
(1)業(yè)務(wù)場景介紹:下面我們以“訪問前端門戶網(wǎng)站商品信息”為業(yè)務(wù)場景,在后端管理平臺添加“熱門商品信息”時也順便將其塞入緩存Redis中,之后前端門戶網(wǎng)站在獲取該商品詳情時直接走緩存Redis查詢,而不走數(shù)據(jù)庫DB查詢,在某種情況下(比如雙11、雙12的熱銷商品),可以緩解數(shù)據(jù)庫的訪問壓力,降低DB的負載!
(2)我們首先開發(fā)一個Controller,用于添加熱門商品信息、并將其塞入緩存Redis中,除此之外,還開發(fā)了前端門戶網(wǎng)站訪問該熱門商品詳情信息的請求方法,其完整的源碼如下所示:
/**
* 字符串String實戰(zhàn)-商品詳情存儲
* @Author:debug (SteadyJack)
* @Link: weixin-> debug0868 qq-> 1948831260
* @Date: 2019/10/29 20:58
**/
@RestController
@RequestMapping("string")
public class StringController {
private static final Logger log= LoggerFactory.getLogger(StringController.class);
@Autowired
private StringService stringService;
//添加熱門商品
@RequestMapping(value = "put",method = RequestMethod.POST,consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
public BaseResponse put(@RequestBody @Validated Item item, BindingResult result){
if (result.hasErrors()){
return new BaseResponse(StatusCode.InvalidParams);
}
BaseResponse response=new BaseResponse(StatusCode.Success);
try {
log.info("--商品信息:{}",item);
stringService.addItem(item);
}catch (Exception e){
log.error("--字符串String實戰(zhàn)-商品詳情存儲-添加-發(fā)生異常:",e.fillInStackTrace());
response=new BaseResponse(StatusCode.Fail.getCode(),e.getMessage());
}
return response;
}
//獲取熱門商品詳情
@RequestMapping(value = "get",method = RequestMethod.GET)
public BaseResponse get(@RequestParam Integer id){
BaseResponse response=new BaseResponse(StatusCode.Success);
try {
response.setData(stringService.getItem(id));
}catch (Exception e){
log.error("--字符串String實戰(zhàn)-商品詳情存儲-添加-發(fā)生異常:",e.fillInStackTrace());
response=new BaseResponse(StatusCode.Fail.getCode(),e.getMessage());
}
return response;
}
}
(3)其中,stringService 顧名思義,即為實現(xiàn)業(yè)務(wù)邏輯的真正實現(xiàn)類!其完整源代碼如下所示:
/**
* @Author:debug (SteadyJack)
* @Link: weixin-> debug0868 qq-> 1948831260
* @Date: 2019/10/29 21:05
**/
@Service
public class StringService {
private static final Logger log= LoggerFactory.getLogger(StringService.class);
@Autowired
private ItemMapper itemMapper;
@Autowired
private StringRedisService redisService;
@Autowired
private ObjectMapper objectMapper;
//添加商品
@Transactional(rollbackFor = Exception.class)
public Integer addItem(Item item) throws Exception{
item.setCreateTime(new Date());
item.setId(null);
itemMapper.insertSelective(item);
Integer id=item.getId();
//保證緩存-數(shù)據(jù)庫雙寫的一致性
if (id>0){
redisService.put(id.toString(),objectMapper.writeValueAsString(item));
}
return id;
}
//獲取商品
public Item getItem(Integer id) throws Exception{
Item item=null;
if (id!=null){
if (redisService.exist(id.toString())){
String result=redisService.get(id.toString()).toString();
log.info("---string數(shù)據(jù)類型,從緩存中取出來的value:{}",result);
if (StrUtil.isNotBlank(result)){
item=objectMapper.readValue(result,Item.class);
}
}else{
log.info("---string數(shù)據(jù)類型,從數(shù)據(jù)庫查詢:id={}",id);
item=itemMapper.selectByPrimaryKey(id);
if (item!=null){
redisService.put(id.toString(),objectMapper.writeValueAsString(item));
}
}
}
return item;
}
}
值得一提的是:
A.我們在 “將熱門商品添加進數(shù)據(jù)庫后 也往緩存中間件Redis塞了一份”,為了保證“雙寫一致性”,我們的做法是:“先保證成功數(shù)據(jù)庫,之后再往緩存Redis塞一份!”
B.“商品信息”是一個實體對象,為了能將該實體對象信息塞入Redis的String類型中,我們需要將其“序列化”,采用的Jackson的序列化機制,將該實體對象序列化為“Json格式的字符串”!
C. 在“獲取熱門商品詳情”時,我們當然是根據(jù)Key直接進行獲取,但由于其結(jié)果是String類型的Json格式字符串常量值,故而我們需要將其“反序列化”,即同樣也是采用Jackson的反序列化機制,將其映射到一個Item實體對象中即可
(4)至此,我們的擼碼環(huán)節(jié)就全部完成了,最后,我們基于Postman進行自測吧:
A.首先當然是添加一個熱銷商品,商品信息為:
{
"code": "book50010",
"name": "分布式中間件實戰(zhàn)(Java版)"
}
發(fā)起Http請求以及得到的響應(yīng)信息如下圖所示:
采用Navicat查看數(shù)據(jù)庫中相應(yīng)表的信息記錄,如下圖所示:
B.最后,當然在Postman是模擬“前端門戶網(wǎng)站”發(fā)起“獲取熱銷商品詳情”的請求啦,如下圖所示:
除此之外,還可以在RedisDesktopManager中查看該商品存儲在緩存中間件Redis的詳情:
好了,本篇文章我們就介紹到這里了,建議各位小伙伴一定要照著文章提供的樣例代碼擼一擼,只有擼過才能知道這玩意是咋用的,否則就成了“空談?wù)摺?!對Redis相關(guān)技術(shù)棧以及實際應(yīng)用場景實戰(zhàn)感興趣的小伙伴可以前往Debug搭建的技術(shù)社區(qū)的課程中心進行學習觀看:https://www.fightjava.com/web/index/course/detail/12 !
其他相關(guān)的技術(shù),感興趣的小伙伴可以關(guān)注底部Debug的技術(shù)公眾號,或者加Debug的微信,拉你進“微信版”的真正技術(shù)交流群!一起學習、共同成長!
補充:
1、本文涉及到的相關(guān)的源代碼可以到此地址,check出來進行查看學習:
https://gitee.com/steadyjack/SpringBootRedis
2、目前Debug已將本文所涉及的內(nèi)容整理錄制成視頻教程,感興趣的小伙伴可以前往觀看學習:https://www.fightjava.com/web/index/course/detail/12
3、關(guān)注一下Debug的技術(shù)微信公眾號,最新的技術(shù)文章、課程以及技術(shù)專欄將會第一時間在公眾號發(fā)布哦!