一 案例分析
-
购物车常见实现方式
-
实现方式一:存储到数据库
- 性能存在瓶颈
-
实现方式二:前端本地存储-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(); }