Redis购物车实现案例-Hash数据结构

一 案例分析

  • 购物车常见实现方式

    • 实现方式一:存储到数据库

      • 性能存在瓶颈
    • 实现方式二:前端本地存储-localstorage-sessionstorage

      • localstorage在浏览器中存储 key/value 对,没有过期时间。
      • sessionstorage在浏览器中存储 key/value 对,在关闭会话窗口后将会删除这些数据。
    • 实现方式三:后端存储到缓存如redis

      • 可以开启AOF持久化防止重启丢失(推荐)

二 相关VO数据准备

public class CartItemVO {
​
    /**
     * 商品id
     */
    private Integer productId;
​
    /**
     * 购买数量
     */
    private Integer buyNum;
​
    /**
     * 商品标题
     */
    private String productTitle;
​
    /**
     * 图片
     */
    private String productImg;
​
    /**
     * 商品单价
     */
    private int price ;
​
    /**
     * 总价格,单价+数量
     */
    private int totalPrice;
​
​
    public int getProductId() {
        return productId;
    }
​
    public void setProductId(int productId) {
        this.productId = productId;
    }
​
    public Integer getBuyNum() {
        return buyNum;
    }
​
    public void setBuyNum(Integer buyNum) {
        this.buyNum = buyNum;
    }
​
    public String getProductTitle() {
        return productTitle;
    }
​
    public void setProductTitle(String productTitle) {
        this.productTitle = productTitle;
    }
​
    public String getProductImg() {
        return productImg;
    }
​
    public void setProductImg(String productImg) {
        this.productImg = productImg;
    }
​
    /**
     * 商品单价 * 购买数量
     * @return
     */
    public int getTotalPrice() {
​
        return this.price*this.buyNum;
    }
​
    public int getPrice() {
        return price;
    }
​
    public void setPrice(int price) {
        this.price = price;
    }
​
    public void setTotalPrice(int totalPrice) {
        this.totalPrice = totalPrice;
    }
}
public class CartVO {
​
    /**
     * 购物项
     */
    private List<CartItemVO> cartItems;
​
​
    /**
     * 购物车总价格
     */
    private Integer totalAmount;
​
​
​
    /**
     * 总价格
     * @return
     */
    public int getTotalAmount() {
        return cartItems.stream().mapToInt(CartItemVO::getTotalPrice).sum();
    }
​
​
​
    public List<CartItemVO> getCartItems() {
        return cartItems;
    }
​
    public void setCartItems(List<CartItemVO> cartItems) {
        this.cartItems = cartItems;
    }
}
@Repository
public class VideoDao {
​
    private static Map<Integer,VideoDO> map = new HashMap<>();
​
    static {
        map.put(1,new VideoDO(1,"工业级PaaS云平台+SpringCloudAlibaba 综合项目实战(完结)","https://xdclass.net",1099));
        map.put(2,new VideoDO(2,"玩转新版高性能RabbitMQ容器化分布式集群实战","https://xdclass.net",79));
        map.put(3,new VideoDO(3,"新版后端提效神器MybatisPlus+SwaggerUI3.X+Lombok","https://xdclass.net",49));
        map.put(4,new VideoDO(4,"玩转Nginx分布式架构实战教程 零基础到高级","https://xdclass.net",49));
        map.put(5,new VideoDO(5,"ssm新版SpringBoot2.3/spring5/mybatis3","https://xdclass.net",49));
        map.put(6,new VideoDO(6,"新一代微服务全家桶AlibabaCloud+SpringCloud实战","https://xdclass.net",59));
    }
​
​
    /**
     * 模拟从数据库找
     * @param videoId
     * @return
     */
    public VideoDO findDetailById(int videoId) {
        return map.get(videoId);
    }
}
​
public class JsonUtil {
​
    // 定义jackson对象
    private static final ObjectMapper MAPPER = new ObjectMapper();
​
    /**
     * 将对象转换成json字符串。
     
     * @return
     */
    public static String objectToJson(Object data) {
        try {
            String string = MAPPER.writeValueAsString(data);
            return string;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
​
    /**
     * 将json结果集转化为对象
     *
     * @param jsonData json数据
     * @param clazz 对象中的object类型
     * @return
     */
    public static <T> T jsonToPojo(String jsonData, Class<T> beanType) {
        try {
            T t = MAPPER.readValue(jsonData, beanType);
            return t;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
​
}

三 接口开发

  • 添加购物车接口
     @RequestMapping("addCart")
        public JsonData addCart(int videoId,int buyNum){
    ​
            //获取购物车
            BoundHashOperations<String, Object, Object> myCart = getMyCartOps();
    ​
            Object cacheObj = myCart.get(videoId+"");
            String result = "";
    ​
            if (cacheObj != null) {
                result = (String) cacheObj;
            }
            if (cacheObj == null) {
                //不存在则新建一个购物项
                CartItemVO cartItem = new CartItemVO();
                //从数据库查询详情,我们这边直接随机写个
    ​
                VideoDO videoDO = videoDao.findDetailById(videoId);
                videoDO.setId(videoId);
    ​
                cartItem.setPrice(videoDO.getPrice());
                cartItem.setBuyNum(buyNum);
                cartItem.setProductId(videoId);
                cartItem.setProductImg(videoDO.getImg());
                cartItem.setProductTitle(videoDO.getTitle());
                myCart.put(videoId+"", JsonUtil.objectToJson(cartItem));
    ​
            } else {
    ​
                //存在则新增数量
                CartItemVO cartItem = JsonUtil.jsonToPojo(result, CartItemVO.class);
                cartItem.setBuyNum(cartItem.getBuyNum() + buyNum);
                myCart.put(videoId+"", JsonUtil.objectToJson(cartItem));
    ​
            }
    ​
            return JsonData.buildSuccess();
    ​
        }

  • 购物车方法抽取
    /**
         * 抽取我的购物车通用方法
         *
         * @return
         */
        private BoundHashOperations<String, Object, Object> getMyCartOps() {
            String cartKey = getCartKey();
            return redisTemplate.boundHashOps(cartKey);
        }
    ​
    ​
        /**
         * 获取购物车的key
         *
         * @return
         */
        private String getCartKey() {
            //从拦截器获取 ,这里写死即可,每个用户不一样
            int userId = 88;
            String cartKey = String.format("product:cart:%s", userId);
            return cartKey;
        }

  • 查看我的购物车
    @GetMapping("/mycart")
        public JsonData findMyCart(){
    ​
            BoundHashOperations<String,Object,Object> myCart = getMyCartOps();
    ​
            List<Object> itemList = myCart.values();
    ​
            List<CartItemVO> cartItemVOList = new ArrayList<>();
    ​
            for(Object item: itemList){
                CartItemVO cartItemVO = JsonUtil.jsonToPojo((String)item,CartItemVO.class);
                cartItemVOList.add(cartItemVO);
            }
    ​
            //封装成cartvo
            CartVO cartVO = new CartVO();
            cartVO.setCartItems(cartItemVOList);
    ​
    ​
            return JsonData.buildSuccess(cartVO);
        }

  • 清空购物车
    @GetMapping("/clear")
    public JsonData clear() {
            String cartKey = getCartKey();
            redisTemplate.delete(cartKey);
             return JsonData.buildSuccess();
    }

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值