电商网站中购物车的实现有很多种方式,这里我介绍两种,第一种是直接用数据库,用户在一个会话期间的所有的对购物车的操作全部都是对数据库的操作,这种方式更新快,可以跨终端跨浏览器实现实时更新,但是比较消耗资源,因为每次操作都是和数据库的一次交互。第二种方式是session+数据库,在一次会话期间,服务器先把用户对购物车的操作放在session中,当用户退出登录或者关闭浏览器的时候再同步到数据库中,这种方式避免了很多对数据库的重复操作,有利于节省资源,提高效率,但是无法实现跨浏览器,跨设备的同步,信息更新也不及时。第一种方式的实现比较简单,在数据库中创建一张购物车表,有四个字段:cart_id,user_id,goods_id,count,这里就不再赘述,主要讲一讲第二种方式。
-
数据结构
把购物车放在session中这种方式的数据结构是HashMap,键是商品的id,值需要另外创建一个类:CartItem,这个类只有两个成员:goods与count,分别记录着商品的信息与商品的数量
package com.qfedu.entity; import lombok.Data; @Data public class CartItem { private FreshGoods freshGoods; private int count; }
-
controller
package com.qfedu.controller; import com.qfedu.entity.Cart; import com.qfedu.entity.CartItem; import com.qfedu.entity.FreshGoods; import com.qfedu.service.CartService; import com.qfedu.service.FreshGoodsService; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.servlet.http.HttpSession; import java.util.HashMap; import java.util.Map; /** * (Cart)表控制层 * * @author makejava * @since 2020-03-24 16:03:32 */ @Controller //@RequestMapping("cart") public class CartController { /** * 服务对象 */ @Resource private CartService cartService; @Resource private FreshGoodsService goodsService; /** * 通过主键查询单条数据 * * @param id 主键 * @return 单条数据 */ //@GetMapping("selectOne") public Cart selectOne(Integer id) { return this.cartService.queryById(id); } @PostMapping("mycart") public String myCart(@RequestParam("fdid") String fdid, HttpSession session){ System.out.println("hehe" + fdid); Object objCart = session.getAttribute("cart"); Map<String, CartItem> cart = null; if(objCart == null){ // 购物车为空 cart = new HashMap<>(); CartItem cartItem = new CartItem(); FreshGoods fg = goodsService.queryById(fdid); cartItem.setCount(1); cartItem.setFreshGoods(fg); cart.put(fdid, cartItem); }else{ // 购物车不为空 cart = (Map<String, CartItem>)objCart; if(cart.containsKey(fdid)){ // 购物车中包含要添加的商品 CartItem cartItem = cart.get(fdid); cartItem.setCount(cartItem.getCount() + 1); cart.put(fdid, cartItem); }else{ FreshGoods fg = goodsService.queryById(fdid); CartItem cartItem = new CartItem(); cartItem.setCount(1); cartItem.setFreshGoods(fg); cart.put(fdid, cartItem); } } session.setAttribute("cart", cart); return "mycart"; } }
这里要进行三次判断,第一种情况是session域中还没有购物车,所以要创建购物车,然后放进去,第二种情况是已经有了购物车但是购物车中还没有要添加的商品,购物车需要新添加一个CartItem,第三种情况是已经有了购物车并且购物车中已经有了要添加的商品,直接在原来的数量的基础上加1.
-
mycart.jsp
<div> <c:if test="${cart != null}"> <div class="occasion-cart"> <div class="snipcart-details top_brand_home_details item_add single-item hvr-outline-out"> </div> </div> <form action="payment" method="post"> <table class="table table-bordered table-striped table-hover"> <tr> <th><input type="checkbox" id="all" onclick="checkAllCart(this.checked)" /></th> <th>pdid</th> <th>pname</th> <th>price</th> <th>discount</th> <th>image</th> <th>count</th> <th>gtid</th> <th>summary</th> </tr> <c:forEach items="${cart}" var="ct"> <tr> <th><input type="checkbox" name="one" onclick="checkOneCart()" value="${ct.key}" /></th> <td> ${ct.key}</td> <td> ${ct.value.freshGoods.goodName}</td> <td> ${ct.value.freshGoods.price}</td> <td> ${ct.value.freshGoods.discount}%</td> <td> ${ct.value.freshGoods.img}</td> <td> ${ct.value.count}</td> <td> ${ct.value.freshGoods.gtid}</td> <td> ${ct.value.count * ct.value.freshGoods.price * ct.value.freshGoods.discount / 100}</td> </tr> </c:forEach> </table> <input type="hidden" name="fdid" value="${freshGoods.fdid}"/> <input type="submit" value="pay" class="button btn-primary btn-success btn-lg" style="width: 200px;" /> </form> </c:if> </div> <jsp:include page="bottom.jsp"/> <script> function checkAllCart(v) { var chOne = document.getElementsByName("one"); for(var i = 0; i < chOne.length; i++){ //alert(); chOne[i].checked = v; } } function checkOneCart() { var chOne = document.getElementsByName("one"); var flag = true; for(var i = 0; i < chOne.length; i++){ if(!chOne[i].checked){ document.getElementById("all").checked = false; flag = false; break; } } if(flag){ document.getElementById("all").checked = true; } } </script>
这个页面的主要操作是展示购物车,重点在于获取Map,还有使用js进行全选操作。