🌟前言
之前的篇章对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数据类型的应用,实际场景的逻辑根据具体需求而定。感谢大家的阅读,希望大家在评论区对此部分内容散发讨论,便于学到更多的知识。