SpringBoot電腦商城項目--增加減少購物車商品數量

1. 持久層

1.1 規劃sql語句

  • 執行更新t_cart表記錄的num值
  • 根據cid查詢購物車的數據是否存在

select * from t_cart where cid=#{cid}

1.2 接口和抽象方法

    /*** 獲取購物車中商品的數據總數* @return 購物車中商品的數據總數*/Cart findByCid(Integer cid);

1.3 xml文件中sql映射

    <select id="findByCid" resultMap="CartEntityMap">select * from t_cart where cid=#{cid}</select>

1.4 測試類中進行測試

@Testpublic void findByCid() {Integer cid = 1;Cart cart = cartMapper.findByCid(cid);System.out.println(cart);}

2. 業務層

2.1 規劃異常

  • 更新時產生的更新異常

  • 查詢時數據是否有訪問的權限

  • 要查詢的數據不存在,CartNotFoundException異常

package com.cy.store.service.ex;public class CartNotFoundException extends ServiceException{public CartNotFoundException() {super();}public CartNotFoundException(String message) {super(message);}public CartNotFoundException(String message, Throwable cause) {super(message, cause);}public CartNotFoundException(Throwable cause) {super(cause);}protected CartNotFoundException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {super(message, cause, enableSuppression, writableStackTrace);}
}

2.2 接口和抽象方法

    /*** 添加購物車數量* @param cid 購物車數據id* @param uid 用戶id* @param username 用戶名* @return 修改后的購物車商品數量*/Integer addNum(Integer cid, Integer uid, String username);/*** 減少購物車數量* @param cid 購物車數據id* @param uid 用戶id* @param username 用戶名* @return 修改后的購物車商品數量*/Integer cutNum(Integer cid, Integer uid, String username);

2.3 實現類實現接口,重寫抽象方法

    /*** 修改購物車商品的數量* @param cid 購物車id* @param uid 用戶id* @param username 用戶名* @return 修改后的商品數量*/@Overridepublic Integer addNum(Integer cid, Integer uid, String username) {
//        判斷數據庫中是否有購物車數據Cart cart = cartMapper.findByCid(cid);if (cart==null){throw new CartNotFoundException("購物車數據不存在");}if (cart.getUid()!=uid){throw new AccessDeniedException("非法訪問");}
//        進行數量+1操作Integer newNum = cart.getNum()+1;Integer rows = cartMapper.updateNumByCid(cid,newNum,username,new Date());
//        如果返回影響行數不為1,則拋出更新數據產生未知的異常if (rows!=1){throw new UpdateException("更新數據時產生未知的異常");}//        返回數據庫中商品的數量return newNum;}/*** 減少購物車商品的數量* @param cid 購物車id* @param uid 用戶id* @param username 用戶名* @return 修改后的商品數量*/@Overridepublic Integer cutNum(Integer cid, Integer uid, String username) {
//        判斷數據庫中是否有購物車數據Cart cart = cartMapper.findByCid(cid);if (cart==null){throw new CartNotFoundException("購物車數據不存在");}if (cart.getUid()!=uid){throw new AccessDeniedException("非法訪問");}Integer newNum = null;if (cart.getNum()!=0){//        進行數量-1操作newNum = cart.getNum()-1;Integer rows = cartMapper.updateNumByCid(cid,newNum,username,new Date());//        如果返回影響行數不為1,則拋出更新數據產生未知的異常if (rows!=1){throw new UpdateException("更新數據時產生未知的異常");}}else {throw new CartNotFoundException("無法減少商品了");}//        返回數據庫中商品的數量return newNum;}
}

3. 控制層

3.1 規劃異常的處理

? ? ? ? 在BaseController中捕獲CartNotFoundException異常


/*** 控制層基類*/
public class BaseController {//操作成功的狀態碼public static final int OK = 200;/*** 全局異常處理器,用于捕獲并處理業務層拋出的異常。** @param e 捕獲的異常對象* @return 返回封裝后的 JsonResult 對象,包含狀態碼和錯誤信息*/
//    該項目中產生了異常,會被統一攔截到此方法中,這個方法此時就充當了請求處理方法,方法的返回值直接給前端瀏覽器,返回給前端的數據中,狀態碼,狀態碼對應信息,數據@ExceptionHandler({ServiceException.class, FileUploadException.class})public JsonResult<Void> handleException(Throwable e) {// 創建一個 JsonResult 實例,并初始化異常消息JsonResult<Void> result = new JsonResult<>(e);// 判斷異常類型,設置對應的狀態碼和提示信息if (e instanceof UsernameDuplicatedException){// 用戶名被占用時返回 400 狀態碼和相應提示result.setState(4000);result.setMessage("用戶名被占用");} else if (e instanceof InsertException){// 插入數據失敗時返回 500 狀態碼和相應提示result.setState(4000);result.setMessage("注冊時產生未知的異常");}else if (e instanceof UsernameNotFoundException){result.setState(4001);result.setMessage("用戶數據不存在");}else if (e instanceof PasswordNotMatchException){result.setState(4002);result.setMessage("用戶密碼錯誤");}else if (e instanceof AddressCountLimitException){result.setState(4003);result.setMessage("收貨地址超出上限");}else if (e instanceof CartNotFoundException){result.setState(4007);result.setMessage("購物車數據不存在");}else if (e instanceof AccessDeniedException){result.setState(4004);result.setMessage("收貨地址數據非法訪問");}else if (e instanceof AddressNotFoundException){result.setState(4005);result.setMessage("收貨地址數據不存在");}else if (e instanceof ProductNotFoundException){result.setState(4006);result.setMessage("商品數據不存在");}else if (e instanceof DeleteException){result.setState(5002);result.setMessage("刪除數據時產生未知的異常");}else if (e instanceof UpdateException){result.setState(5003);result.setMessage("更新數據時產生未知的異常");} else if (e instanceof FileEmptyException) {result.setState(6000);} else if (e instanceof FileSizeException) {result.setState(6001);} else if (e instanceof FileTypeException) {result.setState(6002);} else if (e instanceof FileStateException) {result.setState(6003);} else if (e instanceof FileUploadIOException) {result.setState(6004);}// 返回最終的響應結果return result;}/*** 從Session中獲取當前登錄用戶的uid* * @param session HttpSession對象,用于獲取會話中的用戶ID* @return 當前登錄用戶的uid* * `protected` 表示該方法只能被同一個包內的類或子類訪問。* `final` 表示該方法不能被子類重寫。*/protected final Integer getUidFromSession(HttpSession session) {// 從Session中獲取uid// 從會話中獲取uid屬性并轉換為整數類型返回return Integer.valueOf(session.getAttribute("uid").toString());}/*** 從Session中獲取當前登錄用戶的用戶名* @param session HttpSession對象,用于獲取會話中的用戶名* @return 當前登錄用戶的用戶名*/protected final String getUsernameFromSession(HttpSession session) {// 從Session中獲取當前登錄的用戶名return session.getAttribute("username").toString();}}

?3.2 規劃并實現請求

    /*** 增加購物車商品數量* @param cid 購物車id* @param session 登錄用戶* @return 修改數量*/@RequestMapping("/num/add/{cid}")public JsonResult<Integer> addNum(@PathVariable("cid") Integer cid, HttpSession session) {Integer uid = getUidFromSession(session);String username = getUsernameFromSession(session);Integer data = cartService.addNum(cid, uid, username);return new JsonResult<>(OK, data);}/*** 減少購物車商品數量* @param cid 購物車id* @param session 登錄用戶* @return 修改數量*/@RequestMapping("/num/cut/{cid}")public JsonResult<Integer> cutNum(@PathVariable("cid") Integer cid, HttpSession session) {Integer uid = getUidFromSession(session);String username = getUsernameFromSession(session);Integer data = cartService.cutNum(cid, uid, username);return new JsonResult<>(OK, data);}

3.3 測試

? ? ? ? 啟動項目,先登錄,再通過訪問url地址進行測試

4. 前端代碼

? ? ? ? 增加減少購物車商品數量的邏輯基本上是一樣的

		<script type="text/javascript">
<!--		當頁面加載時發送獲取購物車列表的請求		-->$(document).ready(function() {showCartList();});//展示購物車列表數據function showCartList() {// 清空數據區$("#cart-list").empty();$.ajax({url: "/carts",type: "GET",dataType: "JSON",success: function(json) {var list = json.data;// 遍歷后端響應過來的數據for (var i = 0; i < list.length; i++) {// 給數據進行占位var tr = '<tr>\n' +'<td>\n' +'<input name="cids" value="#{cid}" type="checkbox" class="ckitem" />\n' +'</td>\n' +'<td><img src="..#{image}collect.png" class="img-responsive" /></td>\n' +'<td>#{title}#{msg}</td>\n' +'<td>¥<span id="goodsPrice#{cid}">#{singlePrice}</span></td>\n' +'<td>\n' +'<input type="button" value="-" class="num-btn" onclick="reduceNum(#{cid})" />\n' +'<input id="goodsCount#{cid}" type="text" size="2" readonly="readonly" class="num-text" value="#{num}">\n' +'<input class="num-btn" type="button" value="+" onclick="addNum(#{cid})" />\n' +'</td>\n' +'<td><span id="goodsCast#{cid}">#{totalPrice}</span></td>\n' +'<td>\n' +'<input type="button" onclick="delCartItem(this)" class="cart-del btn btn-default btn-xs" value="刪除" />\n' +'</td>\n' +'</tr>';// 賦值tr = tr.replaceAll(/#{cid}/g, list[i].cid);tr = tr.replaceAll(/#{image}/g, list[i].image);tr = tr.replaceAll(/#{title}/g, list[i].title);tr = tr.replaceAll(/#{singlePrice}/g, list[i].realPrice);tr = tr.replaceAll(/#{num}/g, list[i].num);tr = tr.replaceAll(/#{totalPrice}/g, list[i].realPrice * list[i].num);if (list[i].realPrice < list[i].price) {tr = tr.replace(/#{msg}/g, "比加入時降價" + (list[i].price - list[i].realPrice) + "元");} else {tr = tr.replace(/#{msg}/g, "");}// 每次遍歷完數據,就往頁面中添加一行數據$("#cart-list").append(tr);}},error: function (xhr) {alert("加載購物車列表數據時產生未知的異常"+xhr.status);}});}function addNum(cid) {$.ajax({url: "/carts/num/add/"+cid,type: "POST",dataType: "JSON",success: function (json) {if (json.state == 200) {$("#goodsCount"+cid).val(json.data);// .html() 修改某個標簽的內容var price = $("#goodsPrice"+cid).html();var totalPrice = price * json.data;//將商品總價更新到標簽中$("#goodsCast"+cid).html(totalPrice);} else {alert("增加購物車商品數量失敗"+json.message);}},error: function (xhr) {alert("增加購物車商品數量時產生未知的異常!"+xhr.message);}});}// 減少購物車商品數量function reduceNum(cid) {$.ajax({url: "/carts/num/cut/"+cid,type: "POST",dataType: "JSON",success: function (json) {if (json.state == 200) {$("#goodsCount"+cid).val(json.data);// .html() 修改某個標簽的內容var price = $("#goodsPrice"+cid).html();var totalPrice = price * json.data;//將商品總價更新到標簽中$("#goodsCast"+cid).html(totalPrice);} else {alert("增加購物車商品數量失敗"+json.message);}},error: function (xhr) {alert("增加購物車商品數量時產生未知的異常!"+xhr.message);}});}// $(function() {// 	//返回鏈接// 	$(".link-account").click(function() {// 		location.href = "orderConfirm.html";// 	})// })</script>

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/87974.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/87974.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/87974.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

零基礎學習Redis(13) -- Java使用Redis命令

上期我們學習了如何使用Java連接到redis&#xff0c;這期我們來學習如何在java中使用redis中的一些命令 1. set/get 可以看到jedis類中提供了很多set方法 public static void test1(Jedis jedis) {jedis.flushAll();jedis.set("key1", "v1");jedis.set(&q…

解決OSS存儲桶未創建導致的XML錯誤

前言 在Java開發中&#xff0c;集成對象存儲服務&#xff08;OSS&#xff09;時&#xff0c;開發者常會遇到一個令人困惑的錯誤提示&#xff1a; “This XML file does not appear to have any style information associated with it. The document tree is shown below.” 此…

Spring 表達式語言(SpEL)深度解析:從基礎到高級實戰指南

目錄 一、SpEL是什么&#xff1f;為什么需要它&#xff1f; 核心價值&#xff1a; 典型應用場景&#xff1a; 二、基礎語法快速入門 1. 表達式解析基礎 2. 字面量表示 3. 屬性訪問 三、SpEL核心特性詳解 1. 集合操作 2. 方法調用 3. 運算符大全 4. 類型操作 四、Sp…

算法導論第二十四章 深度學習前沿:從序列建模到創造式AI

第二十四章 深度學習前沿&#xff1a;從序列建模到創造式AI 算法的進化正在重新定義人工智能的邊界 深度學習作為機器學習領域最活躍的分支&#xff0c;正以驚人的速度推動著人工智能的發展。本章將深入探討五大前沿方向&#xff0c;通過原理分析、代碼實現和應用場景展示&…

抽象工廠設計模式

1.問題背景&#xff1a; 現在有兩個產品(Product)分別是手機殼(PhoneCase)和耳機(EarPhone)&#xff0c;但是他們會來自于各個生產廠商&#xff0c;比如說Apple和Android等等 那么至少會有四個產品&#xff0c;分別是安卓手機殼&#xff0c;安卓耳機&#xff0c;蘋果手機殼&a…

GESP 3級 C++ 知識點總結

根據GESP考試大綱 (2024年3月版)&#xff0c;幫大家總結一下GESP 3級 C語言的知識點&#xff1a; 核心目標&#xff1a; 掌握C程序的基本結構&#xff0c;理解并能運用基礎的編程概念解決稍復雜的問題&#xff0c;重點是函數、一維數組和字符串處理。 主要知識點模塊&#x…

騰訊云主動型云蜜罐技術解析:云原生威脅狩獵的革新實踐(基于騰訊云開發者社區技術網頁與行業實踐)

摘要 騰訊云主動型云蜜罐&#xff08;Active Cloud Honeypot&#xff09;通過動態誘捕機制和云原生架構&#xff0c;在威脅檢測效率、攻擊鏈還原深度、防御聯動實時性等維度實現突破。相較于傳統蜜罐&#xff0c;其核心優勢體現在&#xff1a; 部署效率&#xff1a;分鐘級完成…

企業微信wecom/jssdk的使用(入門)

概述 記錄一個企業微信jssdk的使用&#xff0c;因為要用到圖片上傳、掃描二維碼等工具。項目是uniapp開發的h5項目&#xff0c;fastadmin&#xff08;thinkphp5&#xff09;后端 先看官方文檔 https://developer.work.weixin.qq.com/document/path/90547#%E5%BA%94%E7%94%A8…

大零售生態下開源鏈動2+1模式、AI智能名片與S2B2C商城小程序的協同創新研究

摘要&#xff1a;在流量紅利消退、零售形態多元化的背景下&#xff0c;大零售生態成為商業發展的新趨勢。本文聚焦開源鏈動21模式、AI智能名片與S2B2C商城小程序在零售領域的協同應用&#xff0c;探討其如何打破傳統零售邊界&#xff0c;實現流量變現與用戶資產化。研究表明&am…

Scrapy全流程(一)

創建一個scrapy項目:scrapy startproject mySpider 生成一個爬蟲:scrapy genspider douban movie.douban.com 提取數據:完善spider&#xff0c;使用xpath等方法 保存數據:pipeline中保存數據 2 創建scrapy項目 下面以抓取豆瓣top250來學習scrapy的入門使用&#xff1a;豆瓣…

【Elasticsearch】TF-IDF 和 BM25相似性算法

在 Elasticsearch 中&#xff0c;TF-IDF 和 BM25 是兩種常用的文本相似性評分算法&#xff0c;但它們的實現和應用場景有所不同。以下是對這兩種算法的對比以及在 Elasticsearch 中的使用情況&#xff1a; TF-IDF - 定義與原理&#xff1a;TF-IDF 是一種經典的信息檢索算法&am…

【QT】控件二(輸入類控件、多元素控件、容器類控件與布局管理器)

文章目錄 1.輸入類控件1.1 LineEdit1.2 Text Edit1.3 Combo Box1.4 SpinBox1.5 Date Edit & Time Edit1.6 Dial1.7 Slider 2. 多元素控件2.1 List Widget2.2 Table Widget2.3 Tree Widget 3. 容器類控件3.1 Group Box3.2 Tab Widget 4. 布局管理器4.1 垂直布局4.2 水平布局…

【Docker基礎】Docker鏡像管理:docker pull詳解

目錄 1 Docker鏡像基礎概念 1.1 什么是Docker鏡像&#xff1f; 1.2 鏡像與容器的關系 1.3 鏡像倉庫(Registry) 2 docker pull命令詳解 2.1 基本語法 2.2 參數解釋 2.3 拉取鏡像的基本流程 2.4 鏡像分層結構解析 3 docker pull實戰指南 3.1 基本使用示例 3.2 指定鏡…

PixPin:一個強大且免費的截圖貼圖工具

PixPin 是一款國產免費的截圖工具&#xff0c;支持屏幕截圖、屏幕錄制&#xff08;GIF&#xff09;、文字識別&#xff08;OCR&#xff09;以及貼圖等功能。 高效截圖 PixPin 支持自由選擇或自動檢測窗口&#xff0c;自定義截圖區域&#xff0c;像素級精確捕捉&#xff0c;延時…

【測試報告】論壇系統

一、項目背景 1.1 測試目標及測試任務 測試目標旨在保障功能無漏洞、流程順暢&#xff0c;實現多端顯示交互一致&#xff0c;達成高并發場景下響應時間&#xff1c;2 秒等性能指標&#xff0c;抵御 SQL 注入等安全攻擊&#xff0c;提升 UI 易用性與提示友好度&#xff1b; 背…

30天pytorch從入門到熟練(day1)

一、總體工作思路 本項目采用“從零構建”的策略&#xff0c;系統性地開展了深度學習模型的開發與優化工作。其目標在于通過全流程自研方式&#xff0c;深入理解模型構建、訓練優化、推理部署的關鍵技術環節。整體路徑分為以下核心階段&#xff1a; 模型初步構建&#xff1a;以…

Subway Surfers Blast × 亞矩陣云手機:手游矩陣運營的終極變現方案

引爆全球&#xff1a;Subway Surfers Blast的流量紅利?? 隨著Sybo Games最新力作《Subway Surfers Blast》全球上線&#xff0c;這款休閑消除游戲迅速席卷各大應用商店榜單。對于手游推廣者而言&#xff0c;如何高效獲取這波流量紅利&#xff1f;??亞矩陣云手機專業手游推…

mysql join的原理及過程

連接過程 每獲得一條驅動表記錄&#xff0c;就立即到被驅動表尋找匹配的記錄。 對于兩表連接來說&#xff0c;驅動表只會被訪問一遍&#xff0c;但被驅動表卻要被訪問好多遍;具體訪問幾遍取決于對驅動表執行單表查詢后的結果集中有多少條記錄。 ? 對于內連接來說&#xff0…

Hologres的EXPLAIN和EXPLAIN ANALYZE簡介

文章目錄 一、執行計劃1、概念簡介2、使用方式①、EXPLAIN②、EXPLAIN ANALYZE 二、算子解讀1、SCAN2、Index Scan和 Index Seek3、Filter4、Decode5、Redistribution6、Join7、Broadcast8、Shard prune和Shards selected9、ExecuteExternalSQL10、Aggregate11、Sort12、Limit1…

49-Oracle init.ora-PFILE-SPFILE-啟動參數轉換實操

一早出現EMCC掛了&#xff0c;之后發現EMCC依賴的instance 掛了&#xff0c;重啟startup后發現spfile無法啟動。還是和小伙伴把基礎問題搞清。spfile是動態文件、動態文件、動態文件&#xff0c;linux下vi看起來部分亂碼部分是可編輯的&#xff0c;vi即使可以編輯也需要轉換成p…