购物车和订单

前言

购物车和订单的Session版,部分代码如下,包含核心思想。

一、购物车实现

1、Core思想

在这里插入图片描述

2、CartServlet(Session版)

package com.xhu.web;

import com.xhu.pojo.Book;
import com.xhu.pojo.Cart;
import com.xhu.pojo.CartItem;
import com.xhu.service.BookService;
import com.xhu.service.impl.BookServiceImpl;
import com.xhu.utils.ParseUtil;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class CartServlet extends BaseServlet {
    private BookService bs = new BookServiceImpl();

    /**
     * 加入购物车
     *
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    protected void addItem(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.获取商品编号
        int id = ParseUtil.parseString(req.getParameter("id"), 0);
        //2.通过编号获取图书信息
        Book book = bs.getBookById(id);
        //3.把图书信息转化未CartItem对象
        if (book != null) {
            CartItem c = new CartItem(book.getId(), book.getName(), 1, book.getPrice());
            //4.添加CartItem对象
            Cart cart = (Cart) req.getSession().getAttribute("cart");
            if (cart == null)
                cart = new Cart();
            cart.addItem(c);
            req.getSession().setAttribute("cart", cart);
            req.getSession().setAttribute("lastItem",c.getName());
        }
        //5.重定向到商品列表页面,回到原来的地址,该地址会随请求头一起过来,即referer
        resp.sendRedirect(req.getHeader("referer"));
    }

    /**
     * 删除商品
     *
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    protected void deleteItem(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.获取cart对象以及要删除的id
        int id = ParseUtil.parseString(req.getParameter("id"), 0);
        Cart cart = (Cart) req.getSession().getAttribute("cart");
        //2.移除cart中该id的商品
        if (cart != null) cart.deleteItem(id);
        //3.重定向到购物车
        resp.sendRedirect(req.getHeader("referer"));
    }

    /**
     * 清空商品
     *
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    protected void clear(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.将购物车直接remove
        req.getSession().removeAttribute("cart");
        //2.重定向到首页
        resp.sendRedirect(req.getContextPath() + "/index.jsp");
    }

    protected void updateCount(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.获取商品id和数量
        int id = ParseUtil.parseString(req.getParameter("id"), 0);
        int count = ParseUtil.parseString(req.getParameter("count"), 1);
        //2.获取对应id的商品对象
        Cart cart = (Cart) req.getSession().getAttribute("cart");
        //3.修改数量
        if (cart != null)
            cart.updateCount(id, count);
        //4.重定向回去
        resp.sendRedirect(req.getHeader("referer"));
    }
}

3、对Cart建模

package com.xhu.pojo;

import java.math.BigDecimal;
import java.util.*;

/**
 * 对购物车进行建模
 */
public class Cart {
    //private Integer totalCount = 0;
    //private BigDecimal totalPrice = new BigDecimal(0);
    private Map<Integer, CartItem> items = new LinkedHashMap<>();

    public Cart() {
    }

    public Integer getTotalCount() {
        int totalCount = 0;
        for (CartItem value : items.values()) {
            totalCount += value.getCount();
        }
        return totalCount;
    }

    public BigDecimal getTotalPrice() {
        BigDecimal totalPrice = new BigDecimal(0);
        for (CartItem value : items.values()) {
            totalPrice = totalPrice.add(value.getTotalPrice());
        }
        return totalPrice;
    }

    public Map<Integer, CartItem> getItems() {
        return items;
    }

    @Override
    public String toString() {
        return "Cart{" +
                "totalCount=" + getTotalCount() +
                ", totalPrice=" + getTotalPrice() +
                ", items=" + Arrays.toString(items.entrySet().toArray()) +
                '}';
    }

    /**
     * 添加商品项
     *
     * @param cartItem
     */
    public void addItem(CartItem cartItem) {
        //查找商品是否存在,若存在,则数量+1,总金额增加;如果不存在则添加在后面就可以了。
        CartItem c = items.get(cartItem.getId());
        if (c != null) {
            //修改变化的源头,即该item数量+1
            c.setCount(c.getCount() + 1);
            return;
        }
        items.put(cartItem.getId(), cartItem);
    }

    /**
     * 删除商品项
     *
     * @param id
     */
    public void deleteItem(Integer id) {
        //直接修改源头,将该商品删掉就行
        items.remove(id);
    }

    /**
     * 清空购物车
     */
    public void clear() {
        items.clear();
    }

    /**
     * 修改商品数量
     *
     * @param id
     * @param count
     */
    public void updateCount(Integer id, Integer count) {
        //查看是否有该商品,有才修改。
        CartItem c = items.get(id);
        if (c != null) {
            //修改变化的源头,即该item数量+1
            c.setCount(count <= 0 ? 0 : count >= 10000 ? 10000 : count);
            return;
        }
    }
}

4、Cart建模中所需的CartItem

package com.xhu.pojo;

import java.math.BigDecimal;

/**
 * 对购物车商品项建模
 */
public class CartItem {
    private Integer id;
    private String name;
    private Integer count;
    private BigDecimal price;
    //private BigDecimal totalPrice;

    public CartItem() {
    }

    public CartItem(Integer id, String name, Integer count, BigDecimal price) {
        this.id = id;
        this.name = name;
        this.count = count;
        this.price = price;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getCount() {
        return count;
    }

    public void setCount(Integer count) {
        this.count = count;
    }

    public BigDecimal getPrice() {
        return price;
    }

    public void setPrice(BigDecimal price) {
        this.price = price;
    }

    public BigDecimal getTotalPrice() {
        return getPrice().multiply(new BigDecimal(getCount()));
    }

    @Override
    public String toString() {
        return "CartItem{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", count=" + count +
                ", price=" + price +
                ", totalPrice=" + getTotalPrice() +
                '}';
    }
}

二、联合订单

在这里插入图片描述

1、创建订单

protected void saveOrder(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession();
        User user = (User) session.getAttribute("user");
        if (user == null) {
            resp.sendRedirect(req.getContextPath() + "/pages/user/login.jsp");
            return;
        }
        Cart cart = (Cart) session.getAttribute("cart");
        if (cart == null) {
            resp.sendRedirect(req.getContextPath() + "/index.jsp");
            return;
        }
        String orderId = os.createOrder(cart, user.getId());
        if (orderId != null) {
            session.removeAttribute("cart");
            session.setAttribute("orderId", orderId);
        }else session.setAttribute("errorMsg","商品被抢光了");
        //避免表单重复提交,重构向到checkout.jsp
        resp.sendRedirect(req.getContextPath() + "/pages/cart/checkout.jsp");
    }

2、Service层

package com.xhu.service.impl;

import com.xhu.dao.BookDAO;
import com.xhu.dao.OrderDAO;
import com.xhu.dao.OrderItemDAO;
import com.xhu.dao.impl.BookDAOImpl;
import com.xhu.dao.impl.OrderDAOImpl;
import com.xhu.dao.impl.OrderItemDAOImpl;
import com.xhu.pojo.Cart;
import com.xhu.pojo.CartItem;
import com.xhu.pojo.Order;
import com.xhu.pojo.OrderItem;
import com.xhu.service.BookService;
import com.xhu.service.OrderService;
import com.xhu.utils.JDBCUtils;

import java.sql.Connection;
import java.sql.Date;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.*;

public class OrderServiceImpl implements OrderService {
    private OrderDAO od = new OrderDAOImpl();
    private OrderItemDAO oid = new OrderItemDAOImpl();
    private BookDAO bd = new BookDAOImpl();
    private Connection conn;

    @Override
    public String createOrder(Cart cart, int userId) {
        conn = JDBCUtils.getConn();
        try {
            conn.setAutoCommit(false);
            //1.保存订单
            Date date = new Date(Calendar.getInstance().getTime().getTime());
            String orderId = new StringBuilder().append(System.currentTimeMillis()).append(userId).toString();
            Order order = new Order(orderId, date, cart.getTotalPrice(), userId);
            od.saveOrder(conn, order);
            //2.保存订单项
            Map<Integer, CartItem> items = cart.getItems();
            //无则返回
            if (items == null || items.values().size() == 0) {
                conn.rollback();
                return null;
            }
            //有则进行迭代添加
            Iterator<CartItem> iterator = items.values().iterator();
            CartItem next = null;
            String orderItemId = null;
            OrderItem oi = null;
            boolean flag = true;
            while (iterator.hasNext()) {
                next = iterator.next();
                System.out.println(next);
                orderItemId = new StringBuilder().append(System.currentTimeMillis()).append(userId).toString();
                oi = new OrderItem(orderItemId, next.getName(), next.getPrice(), next.getCount(), orderId);
                flag = oid.saveOrderItem(conn, oi) > 0;
                //判断商品是否被抢光
                flag &= bd.updateCountById(conn, next.getId(),next.getCount()) > 0;
                if (!flag) {
                    conn.rollback();
                    return null;
                }
            }
            //3.提交事务并返回true
            conn.commit();
            return orderId;
        } catch (SQLException throwables) {
            try {
                //异常rollback
                conn.rollback();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            throwables.printStackTrace();
        }
        JDBCUtils.close(conn);
        return null;
    }
}

3、更新图书销量和库存

@Override
    public int updateCountById(Connection conn, int id, int count) throws SQLException {
        String sql = "update book set stock = stock - ?,sales = sales + ? where id = ? and stock - ? >= 0";
        return update(conn, sql, count, count, id, count);
    }

总结

1)打好面向对象的基础,代码不是关键,core在于对于需求建模,并拆分业务,最后再写好每一层逻辑。(MVC思想+三层结构解耦)
2)Base Step,
Mining demand -> Modeling demand -> Creating table for model -> POJO -> DAO -> Service -> Servlet -> JSP

参考文献

[1] JavaWeb 尚硅谷

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值