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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈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…