1.1 Redis存储与获取购物车

redisTemplate.boundValueOps("cart_" + userId).get();
redisTemplate.boundValueOps("cart_" + userId).set(carts);

1.2 需求分析

  • 判断当前用户是否登录,如果未登录采用Cookie存储,如果登录则采用Redis存储。登录后要进行Cookie购物车与Redis购物车的合并操作,并清除Cookie购物车。、
  • 说明:Redis的List<Cart>二进制数据。

购物车控制器:

/*** 购物车控制器*/
@RestController
@RequestMapping("/cart")
public class CartController {@Autowiredprivate HttpServletRequest request;@Autowiredprivate HttpServletResponse response;@Reference(timeout = 10000)private CartService cartService;/** 把商品添加到购物车 */@GetMapping("/addCart")public boolean addCart(Long itemId, Integer num){try{// 1. 获取购物车List<Cart> carts = findCart();// 2. 把商品添加到购物车,返回修改后的购物车carts = cartService.addItemToCart(carts, itemId, num);// 获取登录用户名String userId = request.getRemoteUser();// 判断用户是否登录if (StringUtils.isNoneBlank(userId)){ // 已登录/** ############# 已登录的用户,购物车存储到Redis数据库 #################*/cartService.saveCartToRedis(userId, carts);}else{/** ############# 未登录的用户,购物车存储到Cookie #################*/// 3. 把添加后的购物车存储到Cookie中CookieUtils.setCookie(request, response,CookieUtils.CookieName.PINYOUGOU_CART,JSON.toJSONString(carts),3600 * 24, true);}return true;}catch (Exception ex){ex.printStackTrace();}return false;}/** 查看购物车 */@GetMapping("/findCart")public List<Cart> findCart(){// 定义购物车集合List<Cart> carts = null;// 获取登录用户名String userId = request.getRemoteUser();// 判断用户是否登录if (StringUtils.isNoneBlank(userId)){ // 已登录/** ############# 已登录的用户,从Redis数据库中获取购物车数据 #################*/carts = cartService.findCartFromRedis(userId);// 获取Cookie中购物车数据String cartJsonStr = CookieUtils.getCookieValue(request,CookieUtils.CookieName.PINYOUGOU_CART, true);if (StringUtils.isNoneBlank(cartJsonStr)){// 把json格式的字符串转化成List集合List<Cart> cookieCarts = JSON.parseArray(cartJsonStr, Cart.class);// 判断Cookie中购物车集合if (cookieCarts != null && cookieCarts.size() > 0){// 把Cookie中购物车数据 合并 Redis中购物车carts = cartService.megreCart(carts, cookieCarts);// 把合并后得购物车存储到RediscartService.saveCartToRedis(userId, carts);// 删除Cookie中购物车数据CookieUtils.deleteCookie(request, response,CookieUtils.CookieName.PINYOUGOU_CART);}}}else{ // 未登录/** ############# 未登录的用户,从Cookie中获取购物车数据 #################*/// 获取原来的购物车(Cookie) List<Cart>的json格式字符口串 [{},{},{}]String cartJsonStr = CookieUtils.getCookieValue(request,CookieUtils.CookieName.PINYOUGOU_CART, true);System.out.println("cartJsonStr: " + cartJsonStr);// 判断是否为空if (StringUtils.isBlank(cartJsonStr)){cartJsonStr = "[]";}// 把json格式字符串转化成Listcarts = JSON.parseArray(cartJsonStr, Cart.class);}return carts;}
}

购物车服务接口

import java.util.List; /*** 购物车服务接口*/
public interface CartService {/*** 把SKU商品添加购物车* @param carts 购物车集合* @param itemId SKU的id* @param num 购买数据量* @return 修改后得购物车集合*/List<Cart> addItemToCart(List<Cart> carts, Long itemId, Integer num);/** 从Redis数据库中查询用户的购物车 */List<Cart> findCartFromRedis(String userId);/** 把用户的购物车存储到Redis数据库 */void saveCartToRedis(String userId, List<Cart> carts);/** 把Cookie中购物车数据 合并 Redis中购物车 */List<Cart> megreCart(List<Cart> redisCarts, List<Cart> cookieCarts);
}

购物车服务接口实现类

import com.alibaba.dubbo.config.annotation.Service;
import com.pinyougou.cart.Cart;
import com.pinyougou.mapper.ItemMapper;
import com.pinyougou.pojo.Item;
import com.pinyougou.pojo.OrderItem;
import com.pinyougou.service.CartService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.transaction.annotation.Transactional;import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;/*** 购物车服务接口实现类*/
@Service(interfaceName = "com.pinyougou.service.CartService")
@Transactional
public class CartServiceImpl implements CartService {@Autowiredprivate ItemMapper itemMapper;@Autowiredprivate RedisTemplate redisTemplate;/*** 把SKU商品添加购物车* @param carts 购物车集合* @param itemId SKU的id* @param num 购买数据量* @return 修改后得购物车集合*/public List<Cart> addItemToCart(List<Cart> carts, Long itemId, Integer num){try{// 1. 查询SKU商品对象Item item = itemMapper.selectByPrimaryKey(itemId);// 2. 根据商家的id查询商家对应的购物车Cart cart = searchCartBySellerId(carts, item.getSellerId());// 3. 用户没有买过该商家的商品,创建新的购物车if (cart == null){// 代表该用户没有买过该商家的商品// 创建商家的购物车cart = new Cart();// 设置商家idcart.setSellerId(item.getSellerId());// 设置商家店铺名称cart.setSellerName(item.getSeller());// 创建商家对应的购物车集合List<OrderItem> orderItems = new ArrayList<>();// 创建购买的商品OrderItem orderItem = createOrderItem(item, num);// 添加购买的商品orderItems.add(orderItem);// 设置购物车列表cart.setOrderItems(orderItems);// 把商家的购物车添加到用户购物车集合carts.add(cart);}else{// 4. 用户购买过该商家的商品,有没有买过一样的商品?// 获取商家的购物车集合List<OrderItem> orderItems = cart.getOrderItems();// 根据商品的id到商家的购物车集合中查询商品OrderItem orderItem = searchOrderItemByItemId(orderItems, itemId);// 判断orderItem是否为空if (orderItem == null){// 代表没买过该商家的该商品// 创建新的商品orderItem = createOrderItem(item, num);// 添加到商家的购物车orderItems.add(orderItem);}else{// 代表购买过该商家的该商品// 购买数量相加orderItem.setNum(orderItem.getNum() + num);// 购买的总金额orderItem.setTotalFee(new BigDecimal(orderItem.getPrice().doubleValue() * orderItem.getNum()));// 判断购买数量if (orderItem.getNum() == 0){// 从商家的购物车集合中删除该商品orderItems.remove(orderItem);}// 判断商家的购物车集合大小if (orderItems.size() == 0){// 从用户的购物车集合删除商家的购物车carts.remove(cart);}}}return carts;}catch (Exception ex){throw new RuntimeException(ex);}}/** 根据商品的id到商家的购物车集合中查询商品 */private OrderItem searchOrderItemByItemId(List<OrderItem> orderItems, Long itemId) {for (OrderItem orderItem : orderItems){if (orderItem.getItemId().equals(itemId)){return orderItem;}}return null;}/** 把Item转化成OrderItem */private OrderItem createOrderItem(Item item, Integer num) {// 创建OrderItemOrderItem orderItem = new OrderItem();// 设置SKU商品的idorderItem.setItemId(item.getId());// 设置SPU商品的idorderItem.setGoodsId(item.getGoodsId());// 设置商品的标题orderItem.setTitle(item.getTitle());// 设置商品的价格orderItem.setPrice(item.getPrice());// 购买数量orderItem.setNum(num);// 购买总金额(小计)orderItem.setTotalFee(new BigDecimal(item.getPrice().doubleValue() * num));// 设置商品图片orderItem.setPicPath(item.getImage());// 设置商家的idorderItem.setSellerId(item.getSellerId());return orderItem;}/** 根据商家的id查询商家对应的购物车 */private Cart searchCartBySellerId(List<Cart> carts, String sellerId) {// 迭代购物车集合for (Cart cart : carts){// 判断商家idif (cart.getSellerId().equals(sellerId)){return cart;}}return null;}/** 从Redis数据库中查询用户的购物车 */public List<Cart> findCartFromRedis(String userId){System.out.println("=====从Redis数据库获取购物车=======");List<Cart> carts = (List<Cart>) redisTemplate.boundValueOps("cart_" + userId).get();if (carts == null){carts = new ArrayList<>();}return carts;}/** 把用户的购物车存储到Redis数据库 */public void saveCartToRedis(String userId, List<Cart> carts){System.out.println("=====把购物车存储到Redis数据库=======");redisTemplate.boundValueOps("cart_" + userId).set(carts);}/** 把Cookie中购物车数据 合并 Redis中购物车 */public List<Cart> megreCart(List<Cart> redisCarts, List<Cart> cookieCarts){// 迭代Cookie购物车集合for (Cart cart : cookieCarts){for (OrderItem orderItem : cart.getOrderItems()){redisCarts = addItemToCart(redisCarts, orderItem.getItemId(), orderItem.getNum());}}return redisCarts;}
}

Redis存储购物车相关推荐

  1. php使用redis实现购物车功能,ThinkPHP5+Redis实现购物车

    本篇文章是通过ThinkPHP5和Redis实现购物车,功能包括:购物车列表.添加购物车.获取部分商品.获取部分商品总数量.获取全部商品总数量.商品减一.修改商品数量.删除商品.清空购物车,这些功能基 ...

  2. SpringBoot整合Redis实现购物车功能

    目录 项目介绍 开发配置 开发流程 购物车业务流程 开发流程 1.项目结构 2.数据层(DAO) 3.数据层(POJO.VO) 4.Redis配置层 5.服务层(Service) 6.控制层(Cont ...

  3. 使用Redis实现购物车、计数器、好/差评等功能测试【一看就懂】

    衔接上文:(若对Spring整合Redis还不太了解请参考) Spring整合Redis入门详解及基础练习_杨大仙爱篮球-CSDN博客 本文仅做功能测试,展示代码逻辑,后续会发布在项目中如何使用 . ...

  4. 每秒1w+分布式事务--dtm的Redis存储性能测试分析

    概述 之前dtm给出了Mysql作为存储引擎的性能测试报告,在一个普通配置的机器上,2.68w IOPS,4核8G机器上,能够支持大约每秒900+分布式事务,能够满足大部分公司的业务需求. 此次带来的 ...

  5. Redis存储总是心里没底?你大概漏了这些数据结构原理

    上一篇文章<Redis存储总用String?你大概错过了更优的使用方法>我们了解了Redis的数据类型特点与适用场景,本期内容则会着重讲讲Redis内存数据结构与编码,弄清Redis内部到 ...

  6. 阿里云短信验证解决方案(java版)(redis存储)

    阿里云短信验证解决方案(java版)(redis存储) 参考文章: (1)阿里云短信验证解决方案(java版)(redis存储) (2)https://www.cnblogs.com/Amos-Tur ...

  7. 大容量类 Redis 存储的场景补充-pika

    2019独角兽企业重金招聘Python工程师标准>>> 导读 我们在<大容量类 Redis 存储 - 有关 pika 的一切>里介绍过pika的诞生.pika的特点.pi ...

  8. Redis 存储字符串和对象

    今天用redis存储,发现客户端jedis提供的存储方法中存储的类型只有String和byte数据,没有能够存储对象的,网上发现可以序列化存储对象.这就开始了我第一次序列化之旅. 1 测试类 impo ...

  9. php cache缓存 购物车,Yii2使用Redis缓存购物车等数据

    服务器配置Redis Redis下载安装配置 wget http://download.redis.io/releases/redis-stable.tar.gz tar -xvf redis-sta ...

最新文章

  1. Ubuntu 12.04 64位上安装Wine QQ2013
  2. 生成两个表的笛卡尔积
  3. IntelliJ IDEA 的 Build Project/Build Module/构建项目/构建模块
  4. 肖仰华 | SIGIR 2018、WWW2018 知识图谱研究综述
  5. php 后端 轻量 框架,GitHub - 22cloud/mixphp: 轻量 PHP 框架,基于 Swoole 的常驻内存型 PHP 高性能框架 (开发文档完善)...
  6. Android移动开发基础案例教程 第2章 Android UI开发
  7. STM32F103系列选型
  8. 2010年中国城市人均GDP排名
  9. PyTorch笔记 - Dropout: A Simple Way to Prevent Neural Networks from Overfitting
  10. 一个在国内外使用广泛的精密电阻品牌介绍
  11. PySpark | Spark3新特性 | Spark核心概念
  12. 32 任意项级数敛散性的判别法
  13. 技能分享 | 麦肯锡教给我的写作武器:如何讲好一句话
  14. 新手上路——树莓派3B+换源
  15. 程序人生 - 敬酒常识
  16. 主题包网址(Theme)
  17. matlab交互式程序设计示例,matlab交互式程序设计示例
  18. backtrader量化回测,基础篇,附MACD交易回测代码
  19. Windows 7安装软件时无法将注册值写入注册表的处理方法
  20. 【2019年04月22日】A股最便宜的股票

热门文章

  1. c 语言编译程序的首要工作,2017年计算机基础试题选择题「附答案」
  2. imap服务器收缓存pst文件夹,Outlook 转移OST数据文件 IMAP账户
  3. 对混淆矩阵、F1-Score
  4. 快速构建一个简单的对话+问答AI (上)
  5. 移植u-boot-2010.12.tar.bz2版本到s3c2440过程
  6. 跌倒智能监测警报系统市场现状及未来发展趋势分析
  7. 地球重力——黄金维教授,台湾交通大学
  8. 怎么用python下载视频_使用Python从直接URL下载视频
  9. Hbuilder开发移动新闻客户端(二)
  10. 点击左右箭头实现内容滑动