目录

一.购物车实现方式

1.Cookie方式.

2.session方式.

3数据库方式.

二.效果预览 

2.1 未登录提示

 2.2 已登录提示

 2.3 查看"我的购物车"

 三.实现思路

3.1 分清楚商品 订单项  订单的关系

①商品:包含基本信息

 ②订单项:除了商品的基本信息外还包含购买数量和价格小计

③订单:由多个订单项组成 

3.2 表的设计

 3.3 实现登录与否的提示

3.4 订单项的构成

 3.5 形成订单项集合,存到session中

3.6 购物车界面绑值

3.7 解决两个问题

3.7.1 覆盖问题,永远只有一个

3.7.2 加同一商品重复问题

如何不跳转购物车界面?只提示成功但加入到了购物车中?

out.print("");替换之前的跳转

3.8 合计总价格

3.9 实现删除 和修改(从session中)

3.9.1 删除

3.9.2 实现修改

3.10 细节处理

3.10.1 已登录,但购物车为空时

 3.10.2 未登录,点击"我的购物车"【建议参考淘宝】


一.购物车实现方式

1.Cookie方式.

  • 优点: Cookie是存储在客户端的,占用很少的资源,可以减轻服务器的压力。

  • 缺点: 基于Cookie开发的购物车要求用户浏览器必须支持并设置为启用cookie,否则购物车则失效, 如果换一台机器再去登录的话,就会丢失购物车信息。


2.session方式.

  • 优点:session可以与客户端保持同步,不依赖于客户端的设置,它是存储在服务器端的信息,因此比较安全。

  • 缺点:session会占用服务器资源,加大服务器的负荷, 会话具有时效性,一旦超时,购物车中商品信息会丢失。


3数据库方式.

  • 优点:持久化存储,可以分析用户购买行为。

  • 缺点:购物车需要实时操作,数据库的访问量一旦大了,就容易导致发生并发或者直接崩溃,维护成本会增加。


二.效果预览 

2.1 未登录提示

 2.2 已登录提示

 2.3 查看"我的购物车"

 三.实现思路

3.1 分清楚商品 订单项  订单的关系

①商品:包含基本信息

 ②订单项:除了商品的基本信息外还包含购买数量和价格小计

③订单:由多个订单项组成 

3.2 表的设计

 3.3 实现登录与否的提示

<a href="javascript:myf('${g.gid}','${user}')"><i class="bi bi-cart-check"></i></a>

<script type="text/javascript">
            function myf(gid,user) {
                if(user){//有值 登录了
                    alert("亲,已成功加入购物车");
                    //location.href="addCart.do?gid="+gid;       
                }
                else{//没有值  没有登录
                    alert("亲,你还没有登录,请先登录");
                    //location.href="login.jsp";
                }
            }
        </script>

3.4 订单项的构成

 3.5 形成订单项集合,存到session中

//形成订单项集合
List<OrderItem> ls =(List<OrderItem>)session.getAttribute("mycart");
 //接收参数gid
 String gid=req.getParameter("gid");

//实例化一个订单项【缺少ooid和oid!!!】
 OrderItem item = new OrderItem();

 //给其赋值
  item.setGoods(goods);
  item.setOinum(1);//购买数量
 item.calcxj();//计算计算价格的方法
//把订单项加入到集合中
ls.add(item);        
//把这个集合存到session
session.setAttribute("mycart", ls);//键  值
//跳转到购物车界面绑值
resp.sendRedirect("cart.jsp?index=5");
        

3.6 购物车界面绑值

  <!--绑定购物车的值  -->
     <c:forEach items="${mycart}" var="oi">
     <th scope="row">${oi.goods.gname}</th><-- 特别注意:间接取值 -->
     <td>&yen;${oi.goods.gprice}</td>
     <td><img width="80px" src="${oi.goods.gpath}"></td>
     <td><span id="aa${oi.goods.gid}" class="xx">${oi.oiprice}</span>元</td>
  <a οnclick="return confirm('你确定从购物车移除嘛?')" href="deleteCart.do?gid=${oi.goods.gid}"><i class="bi bi-trash3-fill"></i> </a>
  </tr>
             </c:forEach> 

3.7 解决两个问题

3.7.1 覆盖问题,永远只有一个

//先拿购物车
  List<OrderItem> ls =(List<OrderItem>)session.getAttribute("mycart");
 //为空=拿不到
  if(ls==null) {

//没拿到就创建一个新的订单项集合【new一个】 拿到了就用拿到的那个进行装订单项
   ls = new ArrayList<OrderItem>();
    }

3.7.2 加同一商品重复问题

//假设法
        boolean f = false;//假设不存在
        //遍历目前的购物车集合
        for (OrderItem oi : ls) {
            //根据商品编号惊喜判断
            if(oi.getGoods().getGid()==Integer.parseInt(gid)) {
                //改数量 如果存在 在原来的基础上进行增加1
                oi.setOinum(oi.getOinum()+1);
                //改价格小计 c重新计算小计
                oi.calcxj();

                //改变f的状态
                f=true;

                //终止提高性能
                break;
            }
            
        }

        //全部遍历完了 确实不存在
        if(f==false) {
    //实例化一个订单项【缺少ooid和oid!!!】
            OrderItem item = new OrderItem();
         //给其赋值
            item.setGoods(goods);
            item.setOinum(1);//购买数量
            item.calcxj();//计算小计
            //把订单项加入到集合中
            ls.add(item);
        }

如何不跳转购物车界面?只提示成功但加入到了购物车中?

out.print("<script>history.go(-1);</script>");替换之前的跳转

3.8 合计总价格

$(function(){
        //统计价格
            var sum = 0.0;
            //遍历
            $(".xx").each(function(i,v){//下标  值
            //累计求和
            sum+=parseFloat(v.innerHTML);
            });
            //保留1位小数
            sum=sum.toFixed(2);
            //给span标签赋值
            $("#sums").html(sum);
        })
   

//如果仍然出现很多位小数  则采用以下方法保留1位小数

String ss = String.format("%.1f",this.oiprice);
this.oiprice  = Double.parseDouble(ss);  

Sysstem.out.printIn(this.oiprice)

3.9 实现删除 和修改(从session中)

3.9.1 删除

<a onclick="return confirm('你确定从购物车删除嘛?')" href="deleteCart.do?gid=${oi.goods.gid}"><i class="bi bi-trash3-fill"></i> </a>

//接收参数gid
        String gid=req.getParameter("gid");
     //先拿购物车
        List<OrderItem> ls =(List<OrderItem>)session.getAttribute("mycart");
        //遍历目前的购物车集合
        for (OrderItem oi : ls) {
            //找到对应的订单项
            if(oi.getGoods().getGid()==Integer.parseInt(gid)) {
                //将其从集合中移除
                ls.remove(oi);
                break;
            }
        }

        //跳转到购物车界面绑值
        resp.sendRedirect("cart.jsp?index=5");

        

3.9.2 实现修改

//给文本框添加失焦事件  同时取id为当前商品的gid  确保唯一且方便取值

<input id="${oi.goods.gid}  οnblur="mys('${oi.goods.gid}') value="${oi.oiprice}"/> 

 //即要拿id 就直接把id设置成gid
function myf(gid,type) {
//拿文本框的数量
var num=$("#"+gid).val();
 //跳转到servlet
location.href="updateCart.do?gid="+gid+"&num="+num;

        //先拿订单项集合
        List<OrderItem> ls =(List<OrderItem>)session.getAttribute("mycart");
        //遍历目前的购物车集合
        for (OrderItem oi : ls) {
            //找到对应的订单项
            if(oi.getGoods().getGid()==Integer.parseInt(gid)) {
                //修改数量
                oi.setOinum(Integer.parseInt(num));
               //重新结束小计

                oi.calc();
                break;
            }
        }
        
        //跳转到购物车界面绑值
        //resp.sendRedirect("cart.jsp?index=5");

3.10 细节处理

3.10.1 已登录,但购物车为空时

 

 3.10.2 未登录,点击"我的购物车"【建议参考淘宝】

 <!-- 购物车未登录 -->
                    <c:if test="${empty user}">
                        <li class="nav-item ${param.index==5?'active':''}">
                                <a class="nav-link" href="login.jsp">我的购物车</a>
                            </li>

<!--购物车登录了  -->
                    <c:if test="${not empty user}">
                     <li class="nav-item ${param.index==5?'active':''}">
                         <a class="nav-link" href="cart.jsp?index=5">我的购物车</a>
                       </li>

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐