购物车的原理以及实现
  今天模拟京东的购物车实现原理完成了购物车模块的开发,给⼤家分享下。
京东的购物车实现原理:在⽤户登录和不登录的状态下对购物车存⼊cookie还是持久化到redis中的实现。下⾯就来具体说次购物车的实现过程
两种情况:
⽤户登录,购物车存⼊redis中
⽤户未登录,购物车存⼊cookie中
⽐较两种⽅式的优缺点:
 cookie:优点:数据保存在⽤户浏览器中,不占⽤服务端内存;⽤户体检效果好;代码实现简单
     缺点:cookie的存储空间只有4k;更换设备时,购物车信息不能同步;cookie禁⽤,不提供保存
 redis:优点:数据能够持久化;实现了购物车同步
    缺点:增加了数据库的压⼒,速度慢
先介绍使⽤cookie存储购物车的实现思路
1、⽤户未登录状态下,⽤户添加购物车,⾸先从cookie中查询购物车中的商品列表
2、判断cookie的商品列表中是否有要添加的商品信息
3、如果cookie中有该商品信息,将商品的数量相加
4、如果没有,根据商品的id值查询商品信息
5、将商品添加到购物车列表中
6、将购物车列表写⼊cookie中,设置cookie的过期时间
7、将cookie返回给客户端。
购物车的实现:
这⾥直接使⽤商品作为购物项对象,在页⾯中计算购物项的⼩计和购物车的总⾦额
package nyist.e3.pojo;
import java.io.Serializable;
import java.util.Date;
public class TbItem implements Serializable{
private Long id;
private String title;
private String sellPoint;
private Long price;
private Integer num;//作为购物项购买的商品数量
private String barcode;
private String image;//展⽰购物项中的图⽚
private Long cid;
private Byte status;
private Date created;
private Date updated;
public Long getId() {
return id;
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title == null ? null : im();
}
public String getSellPoint() {
return sellPoint;
}
public void setSellPoint(String sellPoint) {
this.sellPoint = sellPoint == null ? null : im();    }
public Long getPrice() {
return price;
}
public void setPrice(Long price) {
this.price = price;
}
public Integer getNum() {
return num;
}
public void setNum(Integer num) {
this.num = num;
}
public String getBarcode() {
return barcode;
}
public void setBarcode(String barcode) {
this.barcode = barcode == null ? null : im();    }
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image == null ? null : im();
}
public Long getCid() {
return cid;
}
public void setCid(Long cid) {
this.cid = cid;
}
public Byte getStatus() {
return status;
}
public void setStatus(Byte status) {
this.status = status;
}
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
}
public Date getUpdated() {
return updated;
}
public void setUpdated(Date updated) {
this.updated = updated;
}
cookie中实现添加购物车的代码:
@Controller
public class ShopCartController {
@Autowired
private TbItemService tbItemService;
@Autowired
private ShopCartService shopCartService;
// 获取过期时间
@Value("${EXPIRE_KEY}")
private Integer EXPIRE_KEY;
@Value("${CART_COOKIE}")
private String CART_COOKIE;
/**
* 需求:将商品加⼊购物车中未登录状态下,将购物超过添加到cookie中
*
* 分析:1、从cookie中获取购物车信息
* 2、判断购物车中的商品,如果添加的商品存在,数量相加,不存在,根据商品id查询商品信息,添加到cookie中
* 3、将购物车列表信息写⼊cookie中
*
*
* @param itemId
* @param num
* @return
*/
@RequestMapping("/cart/add/{itemId}")
public String addCart(@PathVariable Long itemId, @RequestParam(defaultValue = "1") Integer num,
HttpServletRequest request, HttpServletResponse response) {
// 1.获得购物车列表
List<TbItem> itemList = getCartItemList(request);
// ⽤来判断商品是否存在的标志
boolean flag = false;
// 2、循环遍列表中的商品信息
for (TbItem tbItem : itemList) {
/
/ 3、判断添加的商品是否存在
if (Id() == itemId.longValue()) {
// 4、添加的商品在cookie中存在,将数量相加
tbItem.Num() + num);
// 重置标签
flag = true;
// 跳出循环
break;
}
}
if (!flag) {
/
/ cookie中没有添加的商品信息
// 通过商品id查询商品信息
TbItem item = ItemById(itemId);
item.setNum(num);
if (StringUtils.Image())) {
// 取⼀张图⽚⽤于展⽰使⽤
item.Image().split(",")[0]);
}
// 将商品添加购物车
itemList.add(item);
}
/
/将购物车写⼊cookie中
CookieUtils.setCookie(request, response, CART_COOKIE, JsonUtils.objectToJson(itemList),EXPIRE_KEY,true);
return "cartSuccess";
}
}
cookie中查询购物车列表:
思路:
1、根据cookie的name值直接取出商品列表信息
2、将购物车列表添加到model中,返回逻辑视图
private List<TbItem> getCartItemList(HttpServletRequest request) {
String json = CookieValue(request, CART_COOKIE, true);
if (StringUtils.isNotBlank(json)) {
// 返回cookie中取出的数据集合
return JsonUtils.jsonToList(json, TbItem.class);
}
// 返回空集合对象
return new ArrayList<>();
}
@RequestMapping("/cart/cart")
public String getCartList(HttpServletRequest request, HttpServletResponse response, Model model) {
// 从cookie中取出商品信息,
List<TbItem> itemList = getCartItemList(request);
// 将购物车信息返回给页⾯中
model.addAttribute("cartList", itemList);
// 跳转逻辑视图
return "cart";
}
js购物车结算代码
cookie中实现删除购物车中商品的功能:
1、接收页⾯传递的善品id值
2、从cookie中取出购物车列表,进⾏循环遍历,然后遍历的每⼀个商品信息和要删除的商品进⾏对⽐
3、如果存在就从购物车列表中将该商品移除
4、重新将购物车列表写⼊cookie中
5、将cookie信息响应给客户端
@RequestMapping("/cart/delete/{itemId}")
public String deleteCartItem(@PathVariable Long itemId, HttpServletRequest request, HttpServletResponse response) {
List<TbItem> list = getCartItemList(request);
for (TbItem tbItem : list) {
if (Id() == itemId.longValue()) {
break;
}
}
// 删除成功后,将购物车列表写⼊cookie中
CookieUtils.setCookie(request, response, CART_COOKIE, JsonUtils.objectToJson(list), EXPIRE_KEY, true);
// 删除成功后,重定向到购物车列表页⾯
return "redirect:/cart/cart.html";
}
cookie购物车的添加,查询,删除已经实现实现,更改⽅法和删除⽅法实现过程基本⼀样
登录状态下redis购物车的实现
实现redis购物车添加功能
思路:
1、从request域中取出登录⽤户的信息
2、使⽤redis存储购物车列表使⽤redis中的hash数据类型  hash的key 使⽤登录⽤户id值,field的key使⽤商品的id值,将商品的信息作为field的value值
3、完成cookie存储购物车列表的功能
实现的代码:
@Override
public E3Result addCart(Long userId, Long itemId, Integer num) {
try {
// 从redis中取出购物车,判断是否已经有购物项
Boolean hexists = jedisClient.hexists(CART_REDIS_KEY_PRE + ":" + userId + "", itemId + "");
if (hexists) {
// 表⽰购物车中已经有该商品,只需要将该商品的数量相加即可
String hget = jedisClient.hget(CART_REDIS_KEY_PRE + ":" + userId + "", itemId + "");
// 将数量相加
TbItem item = JsonUtils.jsonToPojo(hget, TbItem.class);
item.Num() + num);
jedisClient.hset(CART_REDIS_KEY_PRE + ":" + userId + "", itemId + "", JsonUtils.objectToJson(item));
return E3Result.ok();
}
// 表⽰购物车中没有要添加的商品信息
// 根据商品的id查询商品的信息
TbItem item = itemMapper.selectByPrimaryKey(itemId);
item.setNum(num);
if (StringUtils.Image())) {
item.Image().split(",")[0]);
}
// 将商品信息存⼊购物车中
jedisClient.hset(CART_REDIS_KEY_PRE + ":" + userId + "", itemId + "", JsonUtils.objectToJson(item));
return E3Result.ok();
} catch (Exception e) {
e.printStackTrace();
}
return E3Result.build(400, "商品添加购物车失败");
}
展⽰登录状态下的购物车列表:需要将cookie中的购物车和redis中的购物车整合
1、从cookie中取出购物车列表对象
2、从redis中取出购物车对象
3、将cookie中的购物车列表和redis中的购物车列表整合(取出cookie中的购物车列表,然后添加到redis购物车中即可)5、最终展⽰的结果以redis中的购物车为主
/**
* cookie中的购物车和redis中的购物车进⾏整合
*/
@Override
public E3Result mergeCart(Long userId, List<TbItem> itemList) {
for (TbItem tbItem : itemList) {
// 只需要调⽤登录状态下添加购物车业务处理逻辑即可
addCart(userId, Id(), Num());
}
return E3Result.ok();
}
redis购物车中删除购物项
将⽤户的id值和商品的id值分别作为hahs的key和field的key,调⽤redis中的hdel(String field)即可完成删除功能/**
* 删除购物车
*
* @return
*
*/
@Override
public E3Result deleteCartItem(Long id, Long itemId) {
Long hdel = jedisClient.hdel(CART_REDIS_KEY_PRE + ":" + id + "", itemId + "");
System.out.println("删除购物车购物项为"+hdel);
return E3Result.ok();
}
redis购物车中更新购买商品的数量
/**
* 更新购物车中商品的数量
*/
@Override
public E3Result updateRedisNum(Long id, Long itemId, Integer num) {
// 取出需要更改数量的商品信息
String hget = jedisClient.hget(CART_REDIS_KEY_PRE + ":" + id + "", itemId + "");
// 将取出的json数据转换为商品对象,然后更新数量
TbItem item = JsonUtils.jsonToPojo(hget, TbItem.class);
item.setNum(num);
// 更新成功后,将数据写到redis购物车中
jedisClient.hset(CART_REDIS_KEY_PRE + ":" + id + "", itemId + "", JsonUtils.objectToJson(item));
return E3Result.ok();
}
当⽤户点击去结算时:跳转到订单确认页⾯
1、⽣成订单详情

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。