?????作者名稱:DaenCode
??作者簡(jiǎn)介:啥技術(shù)都喜歡搗鼓搗鼓,喜歡分享技術(shù)、經(jīng)驗(yàn)、生活。
??人生感悟:嘗盡人生百味,方知世間冷暖。
??所屬專欄:Redis從頭學(xué)
??前言
之前的篇章對(duì)Redis的String、List數(shù)據(jù)類型已經(jīng)做出了具體分析,并舉例說(shuō)明了其具體的實(shí)戰(zhàn)場(chǎng)景。本文就結(jié)合Hash數(shù)據(jù)類型結(jié)構(gòu)的特性,一起探討其實(shí)戰(zhàn)中的應(yīng)用場(chǎng)景,并以購(gòu)物車實(shí)戰(zhàn)為例。
??Hash數(shù)據(jù)類型分析
Redis中的Hash數(shù)據(jù)類型是一種存儲(chǔ)鍵值對(duì)的數(shù)據(jù)結(jié)構(gòu),其中鍵是唯一的,可以是字符串,整數(shù)或浮點(diǎn)數(shù)。以下是對(duì)其結(jié)構(gòu)的分析:
- 使用類似
字典的方式來(lái)存儲(chǔ)數(shù)據(jù)
,可以高效的進(jìn)行插入、更新、刪除和查找操作。 - 內(nèi)部實(shí)現(xiàn)上采用
哈希表作為底層數(shù)據(jù)結(jié)構(gòu)
。通過(guò)hash函數(shù)將鍵映射到哈希表的槽位,每個(gè)槽位存儲(chǔ)一個(gè)或者多個(gè)鍵值對(duì)。
??Hash類型實(shí)戰(zhàn)應(yīng)用場(chǎng)景
通過(guò)上述對(duì)Hash類型的分析,可以結(jié)合實(shí)際需求選擇適合Hash類型結(jié)構(gòu)的場(chǎng)景。本文主要演示購(gòu)物車功能的演示代碼。
- 緩存:Hash數(shù)據(jù)類型非常適合用于緩存數(shù)據(jù),例如存儲(chǔ)用戶信息、配置信息等??梢允褂肏ash的字段作為鍵,字段對(duì)應(yīng)的值存儲(chǔ)具體的數(shù)據(jù)。這樣可以減少對(duì)數(shù)據(jù)庫(kù)或其他數(shù)據(jù)源的頻繁查詢,提高系統(tǒng)性能。
- 對(duì)象存儲(chǔ):如果需要將一個(gè)對(duì)象存儲(chǔ)在Redis中,可以使用Hash數(shù)據(jù)類型。對(duì)象的各個(gè)屬性可以作為Hash的字段,屬性值作為Hash字段對(duì)應(yīng)的值,這樣可以方便地獲取、更新對(duì)象的某個(gè)屬性,而不需要加載整個(gè)對(duì)象。
- 數(shù)據(jù)分片:如果需要將大量數(shù)據(jù)分散存儲(chǔ)在多個(gè)Redis實(shí)例中,可以使用Hash數(shù)據(jù)類型進(jìn)行數(shù)據(jù)分片??梢愿鶕?jù)某個(gè)字段的哈希值來(lái)確定數(shù)據(jù)應(yīng)該存儲(chǔ)在哪個(gè)實(shí)例中,以實(shí)現(xiàn)分布式存儲(chǔ)。
購(gòu)物車功能
生活中的例子
可以參照淘寶中的購(gòu)物車來(lái)實(shí)現(xiàn)其功能。紅色標(biāo)注部分為購(gòu)物車,藍(lán)色標(biāo)注部分為購(gòu)物項(xiàng)。購(gòu)物車內(nèi)包含很多個(gè)購(gòu)物項(xiàng)
。
存儲(chǔ)分析
根據(jù)上述例子結(jié)合購(gòu)物車以及購(gòu)物項(xiàng)的關(guān)系,數(shù)據(jù)在redis中存儲(chǔ)的樣子,大概如下圖所示:
實(shí)現(xiàn)步驟
- 創(chuàng)建一個(gè)購(gòu)物車實(shí)體類Cart。字段內(nèi)容包含字段包含id、title、以及List<CartItem>購(gòu)物項(xiàng)的list集合、totalAmmount總價(jià)。
- 創(chuàng)建購(gòu)物項(xiàng)實(shí)體類。字段內(nèi)容包含goodId、goodTitle、goodImg、price、totalPrice購(gòu)物項(xiàng)總價(jià)、buyNums購(gòu)買數(shù)量。
- 編寫獲取購(gòu)物車信息以及在購(gòu)物車中添加商品信息的接口。
購(gòu)物車Cart類
要注意計(jì)算購(gòu)物車的總價(jià)格=購(gòu)物項(xiàng)價(jià)格之和。 return cartItemList.stream().mapToInt(CartItem::getTotalPrice).sum();
public class Cart {
private Integer id;
private String title;
private List<CartItem> cartItemList;
private Integer totalAmmount;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public List<CartItem> getCartItemList() {
return cartItemList;
}
public void setCartItemList(List<CartItem> cartItemList) {
this.cartItemList = cartItemList;
}
public Integer getTotalAmmount() {
//計(jì)算購(gòu)物車的總價(jià)格
return cartItemList.stream().mapToInt(CartItem::getTotalPrice).sum();
}
public void setTotalAmmount(Integer totalAmmount) {
this.totalAmmount = totalAmmount;
}
}
CartItem購(gòu)物項(xiàng)類
其中的goodId-商品ID、goodTitle-商品名稱、goodImag-商品封面、price-商品單價(jià)、totalPrice-商品總價(jià)、buyNums-購(gòu)買數(shù)量。
public class CartItem {
private Integer goodId;
private String goodTitle;
private String goodImag;
private Integer price;
private Integer totalPrice;
private int buyNums;
//省略getter、setter
}
獲取個(gè)人購(gòu)物車
解析:
- 從Redis中獲取當(dāng)前用戶的key所對(duì)應(yīng)的購(gòu)物車數(shù)據(jù)。
- 獲取購(gòu)物車數(shù)據(jù)中的購(gòu)物項(xiàng)。
- 對(duì)購(gòu)物項(xiàng)數(shù)據(jù)進(jìn)行解析并以此遍歷轉(zhuǎn)為對(duì)象,放到購(gòu)物項(xiàng)列表中。
- 將購(gòu)物項(xiàng)列表添加到購(gòu)物車中。
流程圖如下:
public JsonData getPersonalCart(int userId) throws IOException {
//購(gòu)物項(xiàng)列表
List<CartItem> cartItemList=new ArrayList<>();
//購(gòu)物車
Cart cart=new Cart();
//從redis中獲取購(gòu)物車。
BoundHashOperations<String,Object,Object> personalCart=getCarts(userId);
//對(duì)personalCart的數(shù)據(jù)進(jìn)行解析,轉(zhuǎn)為json格式。
//1.獲取購(gòu)物車數(shù)據(jù)中的購(gòu)物項(xiàng)。
List<Object> items=personalCart.values();
//2.對(duì)購(gòu)物項(xiàng)進(jìn)行遍歷,并轉(zhuǎn)為對(duì)象類型
for(Object item:items){
ObjectMapper objectMapper=new ObjectMapper();
//3.轉(zhuǎn)為對(duì)象格式
CartItem cartItem=objectMapper.readValue((String) item,CartItem.class);
//4.存儲(chǔ)到購(gòu)物項(xiàng)列表中
cartItemList.add(cartItem);
}
//5.購(gòu)物項(xiàng)列表放入購(gòu)物車
cart.setCartItemList(cartItemList);
return JsonData.buildSuccess(cart);
}
//從redis獲取購(gòu)物車數(shù)據(jù)
public BoundHashOperations<String,Object,Object> getCarts(int userId){
String key="shopping:"+userId;
return redisTemplate.boundHashOps(key);
}
添加購(gòu)物車
首先,我們需要理解這個(gè)流程。這個(gè)流程主要包括以下幾個(gè)步驟:
- 獲取個(gè)人購(gòu)物車
- 根據(jù)當(dāng)前商品id提取個(gè)人購(gòu)物車數(shù)據(jù)
- 如果個(gè)人購(gòu)物車數(shù)據(jù)存在當(dāng)前商品id,則進(jìn)行數(shù)量的增減并存入redis數(shù)據(jù)庫(kù);若不存在,則獲取當(dāng)前商品信息,并將商品信息存入到redis的hash中。
接下來(lái),我們將這個(gè)流程整理成mermaid流程圖的形式:
public JsonData addCart(int userId,int goodId,int buyNums){
//添加購(gòu)物車之前,需要先獲取個(gè)人購(gòu)物車
BoundHashOperations<String,Object,Object> myCart=getCarts(userId);
//判斷購(gòu)物車是否有這個(gè)商品,有商品則增加其數(shù)量,無(wú)商品增加其信息
//獲取當(dāng)前商品信息,
Object cacheGood=myCart.get(goodId+"");
if (cacheGood==null){
//redis中添加商品信息
//首先獲取商品詳情信息
XxxGood xxxGood=xxxService.findDetailById(goodId);
//購(gòu)物項(xiàng)中添加商品信息
CartItem cartItem=new CartItem();
cartItem.setGoodId(goodId);
cartItem.setPrice(xxxGood.getPrice());
//....其他信息
//將購(gòu)物項(xiàng)添加到redis中
myCart.put(goodId+"",cartItem);
}else {
//增加購(gòu)買數(shù)量,需要將當(dāng)前商品轉(zhuǎn)為對(duì)象格式
CartItem cartItem=(CartItem)cacheGood;
cartItem.setBuyNums(cartItem.getBuyNums()+buyNums);
//存入到購(gòu)物車中
myCart.put(goodId,cartItem);
}
return JsonData.buildSuccess();
}
清空購(gòu)物車
public JsonData clearMyCart(int userId){
String key="shopping:"+userId;
redisTemplate.delete(key);
return JsonData.buildSuccess();
}
??寫在最后
有關(guān)于Redis中的Hash數(shù)據(jù)類型實(shí)戰(zhàn)應(yīng)用場(chǎng)景到此就結(jié)束了。功能演示代碼的邏輯簡(jiǎn)單,目的是理解Hash數(shù)據(jù)類型的應(yīng)用,實(shí)際場(chǎng)景的邏輯根據(jù)具體需求而定。感謝大家的閱讀,希望大家在評(píng)論區(qū)對(duì)此部分內(nèi)容散發(fā)討論,便于學(xué)到更多的知識(shí)。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-665231.html
文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-665231.html
到了這里,關(guān)于【Redis從頭學(xué)-6】Redis中的Hash數(shù)據(jù)類型實(shí)戰(zhàn)場(chǎng)景之購(gòu)物車的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!