🧑💻作者名称:DaenCode
🎤作者简介:啥技术都喜欢捣鼓捣鼓,喜欢分享技术、经验、生活。
😎人生感悟:尝尽人生百味,方知世间冷暖。
📖所属专栏:Redis从头学
文章目录
- 🌟前言
- 🌟Hash数据类型分析
- 🌟Hash类型实战应用场景
- 购物车功能
- 生活中的例子
- 存储分析
- 实现步骤
- 购物车Cart类
- CartItem购物项类
- 获取个人购物车
- 添加购物车
- 清空购物车
- 🌟写在最后
🌟前言
之前的篇章对Redis的String、List数据类型已经做出了具体分析,并举例说明了其具体的实战场景。本文就结合Hash数据类型结构的特性,一起探讨其实战中的应用场景,并以购物车实战为例。
🌟Hash数据类型分析
Redis中的Hash数据类型是一种存储键值对的数据结构,其中键是唯一的,可以是字符串,整数或浮点数。以下是对其结构的分析:
- 使用类似
字典的方式来存储数据
,可以高效的进行插入、更新、删除和查找操作。 - 内部实现上采用
哈希表作为底层数据结构
。通过hash函数将键映射到哈希表的槽位,每个槽位存储一个或者多个键值对。
🌟Hash类型实战应用场景
通过上述对Hash类型的分析,可以结合实际需求选择适合Hash类型结构的场景。本文主要演示购物车功能的演示代码。
- 缓存:Hash数据类型非常适合用于缓存数据,例如存储用户信息、配置信息等。可以使用Hash的字段作为键,字段对应的值存储具体的数据。这样可以减少对数据库或其他数据源的频繁查询,提高系统性能。
- 对象存储:如果需要将一个对象存储在Redis中,可以使用Hash数据类型。对象的各个属性可以作为Hash的字段,属性值作为Hash字段对应的值,这样可以方便地获取、更新对象的某个属性,而不需要加载整个对象。
- 数据分片:如果需要将大量数据分散存储在多个Redis实例中,可以使用Hash数据类型进行数据分片。可以根据某个字段的哈希值来确定数据应该存储在哪个实例中,以实现分布式存储。
购物车功能
生活中的例子
可以参照淘宝中的购物车来实现其功能。红色标注部分为购物车,蓝色标注部分为购物项。购物车内包含很多个购物项
。
存储分析
根据上述例子结合购物车以及购物项的关系,数据在redis中存储的样子,大概如下图所示:
实现步骤
- 创建一个购物车实体类Cart。字段内容包含字段包含id、title、以及List<CartItem>购物项的list集合、totalAmmount总价。
- 创建购物项实体类。字段内容包含goodId、goodTitle、goodImg、price、totalPrice购物项总价、buyNums购买数量。
- 编写获取购物车信息以及在购物车中添加商品信息的接口。
购物车Cart类
要注意计算购物车的总价格=购物项价格之和。
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() {
//计算购物车的总价格
return cartItemList.stream().mapToInt(CartItem::getTotalPrice).sum();
}
public void setTotalAmmount(Integer totalAmmount) {
this.totalAmmount = totalAmmount;
}
}
CartItem购物项类
其中的goodId-商品ID、goodTitle-商品名称、goodImag-商品封面、price-商品单价、totalPrice-商品总价、buyNums-购买数量。
public class CartItem {
private Integer goodId;
private String goodTitle;
private String goodImag;
private Integer price;
private Integer totalPrice;
private int buyNums;
//省略getter、setter
}
获取个人购物车
解析:
- 从Redis中获取当前用户的key所对应的购物车数据。
- 获取购物车数据中的购物项。
- 对购物项数据进行解析并以此遍历转为对象,放到购物项列表中。
- 将购物项列表添加到购物车中。
流程图如下:
public JsonData getPersonalCart(int userId) throws IOException {
//购物项列表
List<CartItem> cartItemList=new ArrayList<>();
//购物车
Cart cart=new Cart();
//从redis中获取购物车。
BoundHashOperations<String,Object,Object> personalCart=getCarts(userId);
//对personalCart的数据进行解析,转为json格式。
//1.获取购物车数据中的购物项。
List<Object> items=personalCart.values();
//2.对购物项进行遍历,并转为对象类型
for(Object item:items){
ObjectMapper objectMapper=new ObjectMapper();
//3.转为对象格式
CartItem cartItem=objectMapper.readValue((String) item,CartItem.class);
//4.存储到购物项列表中
cartItemList.add(cartItem);
}
//5.购物项列表放入购物车
cart.setCartItemList(cartItemList);
return JsonData.buildSuccess(cart);
}
//从redis获取购物车数据
public BoundHashOperations<String,Object,Object> getCarts(int userId){
String key="shopping:"+userId;
return redisTemplate.boundHashOps(key);
}
添加购物车
首先,我们需要理解这个流程。这个流程主要包括以下几个步骤:
- 获取个人购物车
- 根据当前商品id提取个人购物车数据
- 如果个人购物车数据存在当前商品id,则进行数量的增减并存入redis数据库;若不存在,则获取当前商品信息,并将商品信息存入到redis的hash中。
接下来,我们将这个流程整理成mermaid流程图的形式:
public JsonData addCart(int userId,int goodId,int buyNums){
//添加购物车之前,需要先获取个人购物车
BoundHashOperations<String,Object,Object> myCart=getCarts(userId);
//判断购物车是否有这个商品,有商品则增加其数量,无商品增加其信息
//获取当前商品信息,
Object cacheGood=myCart.get(goodId+"");
if (cacheGood==null){
//redis中添加商品信息
//首先获取商品详情信息
XxxGood xxxGood=xxxService.findDetailById(goodId);
//购物项中添加商品信息
CartItem cartItem=new CartItem();
cartItem.setGoodId(goodId);
cartItem.setPrice(xxxGood.getPrice());
//....其他信息
//将购物项添加到redis中
myCart.put(goodId+"",cartItem);
}else {
//增加购买数量,需要将当前商品转为对象格式
CartItem cartItem=(CartItem)cacheGood;
cartItem.setBuyNums(cartItem.getBuyNums()+buyNums);
//存入到购物车中
myCart.put(goodId,cartItem);
}
return JsonData.buildSuccess();
}
清空购物车
public JsonData clearMyCart(int userId){
String key="shopping:"+userId;
redisTemplate.delete(key);
return JsonData.buildSuccess();
}
🌟写在最后
有关于Redis中的Hash数据类型实战应用场景到此就结束了。功能演示代码的逻辑简单,目的是理解Hash数据类型的应用,实际场景的逻辑根据具体需求而定。感谢大家的阅读,希望大家在评论区对此部分内容散发讨论,便于学到更多的知识。