首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

網上圖書商城實戰(四):購物車模塊完整實現——資料庫設計、實體、DAO、Service、前端 JS 全解析

     編輯:Java 綜合教學

網上圖書商城實戰(四):購物車模塊完整實現

本文詳細記錄購物車模塊的資料庫設計、實體類(含 BigDecimal 精確計算)、DAO/Service 核心邏輯、前端 jQuery 互動(增刪改查、全選、批量刪除、結算)完整代碼。

1. 資料庫設計:獨立購物車表

不使用 Session/Cookie,採用資料庫表持久化,支援跨裝置、登入後合併購物車。

CREATE TABLE `t_cartitem` (
  `cartItemId` char(32) NOT NULL COMMENT '主鍵',
  `quantity` int(11) NOT NULL COMMENT '數量',
  `bid` char(32) NOT NULL COMMENT '圖書ID',
  `uid` char(32) NOT NULL COMMENT '用戶ID',
  `orderBy` int(11) NOT NULL COMMENT '排序',
  PRIMARY KEY (`cartItemId`),
  KEY `FK_cartitem_book` (`bid`),
  KEY `FK_cartitem_user` (`uid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

購物車表結構

2. CartItem 實體:BigDecimal 精確計算小計

public class CartItem {
    private String cartItemId;
    private int quantity;
    private Book book;
    private User user;

    // 使用 BigDecimal 避免浮點數誤差
    public double getSubtotal() {
        BigDecimal price = new BigDecimal(book.getCurrPrice() + "");
        BigDecimal qty = new BigDecimal(quantity + "");
        return price.multiply(qty).doubleValue();
    }
    // getter/setter 略
}

3. 核心業務邏輯

查詢用戶購物車條目(多表聯查)

public List<CartItem> findByUser(String uid) throws SQLException {
    String sql = "SELECT * FROM t_cartitem c, t_book b WHERE c.bid=b.bid AND uid=? ORDER BY c.orderBy";
    List<Map<String,Object>> mapList = qr.query(sql, new MapListHandler(), uid);
    return toCartItemList(mapList);
}

添加條目:合併同款圖書數量

public void add(CartItem cartItem) {
    try {
        // 1. 檢查是否已存在相同圖書
        CartItem existing = cartItemDao.findByUidAndBid(cartItem.getUser().getUid(), cartItem.getBook().getBid());
        if (existing == null) {
            cartItem.setCartItemId(CommonUtils.uuid());
            cartItemDao.addCartItem(cartItem);
        } else {
            // 2. 存在則合併數量
            int newQty = existing.getQuantity() + cartItem.getQuantity();
            cartItemDao.updateQuantity(existing.getCartItemId(), newQty);
        }
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

修改數量 / 批量刪除 / 結算載入

// 修改數量
public void updateQuantity(String cartItemId, int quantity) {
    cartItemDao.updateQuantity(cartItemId, quantity);
}

// 批量刪除
public void batchDelete(String cartItemIds) {
    String[] ids = cartItemIds.split(",");
    for (String id : ids) {
        cartItemDao.delete(id);
    }
}

// 結算:載入勾選的條目
public List<CartItem> loadCartItems(String cartItemIds) {
    String[] ids = cartItemIds.split(",");
    String placeholders = String.join(",", Collections.nCopies(ids.length, "?"));
    String sql = "SELECT * FROM t_cartitem c, t_book b WHERE c.bid=b.bid AND c.cartItemId IN (" + placeholders + ")";
    return qr.query(sql, new MapListHandler(), (Object[]) ids);
}

4. 前端互動:cartlist.jsp 核心 JS

完整代碼涵蓋:總計計算、全選/反選、數量增減(AJAX)、批量刪除、結算提交。

<script>
$(function() {
    showTotal(); // 初始化總計

    // 全選
    $("#selectAll").click(function() {
        var checked = $(this).prop("checked");
        $(":checkbox[name=checkboxBtn]").prop("checked", checked);
        setJieSuan(checked);
        showTotal();
    });

    // 單選聯動全選
    $(":checkbox[name=checkboxBtn]").click(function() {
        var all = $(":checkbox[name=checkboxBtn]").length;
        var checked = $(":checkbox[name=checkboxBtn]:checked").length;
        $("#selectAll").prop("checked", all === checked);
        setJieSuan(checked > 0);
        showTotal();
    });

    // 減號
    $(".jian").click(function() {
        var id = $(this).attr("id").substring(0, 32);
        var qty = parseInt($("#" + id + "Quantity").val());
        if (qty === 1) {
            if (confirm("確定刪除該條目?")) {
                location = "/goods/CartItemServlet?method=batchDelete&cartItemIds=" + id;
            }
        } else {
            sendUpdateQuantity(id, qty - 1);
        }
    });

    // 加號
    $(".jia").click(function() {
        var id = $(this).attr("id").substring(0, 32);
        var qty = parseInt($("#" + id + "Quantity").val());
        sendUpdateQuantity(id, qty + 1);
    });
});

// AJAX 更新數量
function sendUpdateQuantity(id, qty) {
    $.ajax({
        url: "/goods/CartItemServlet",
        data: {method:"updateQuantity", cartItemId:id, quantity:qty},
        type: "POST", dataType: "json",
        success: function(res) {
            $("#" + id + "Quantity").val(res.quantity);
            $("#" + id + "Subtotal").text(res.subtotal);
            showTotal();
        }
    });
}

// 計算總計
function showTotal() {
    var total = 0;
    $(":checkbox[name=checkboxBtn]:checked").each(function() {
        var id = $(this).val();
        total += Number($("#" + id + "Subtotal").text());
    });
    $("#total").text(round(total, 2)); // round.js 保留兩位小數
}

// 結算提交
function jiesuan() {
    var ids = [];
    $(":checkbox[name=checkboxBtn]:checked").each(function() {
        ids.push($(this).val());
    });
    $("#cartItemIds").val(ids.join(","));
    $("#hiddenTotal").val($("#total").text());
    $("#jieSuanForm").submit();
}
</script>

5. JS 四捨五入工具:round.js

function round(num, dec) {
    var str = num + "", idx = str.indexOf(".");
    if (idx < 0) return num;
    var curDec = str.length - idx - 1;
    if (dec < curDec) {
        var factor = Math.pow(10, dec);
        return Math.round(num * factor) / factor;
    }
    return num;
}

6. 關鍵頁面截圖

購物車頁面

購物車模塊展示了資料庫持久化、精確金額計算、AJAX 異步互動、前後端協作的完整閉環,是電商系統的核心組件。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved