当前位置: 首页 > news >正文

SpringBoot项目--电脑商城【增加/减少购物车商品数量】

1.持久层[Mapper]

1.1规划需要执行的SQL语句

1.更新该商品的数量.此SQL语句无需重复开发

update t_cart set num=?,modified_user=?,modified_time=? where cid=?

2.首先进行查询需要操作的购物车数据信息【查看该条数据是否存在】

SELECT * FROM t_cart WHERE cid=?

2.接口和抽象方法

在CartMapper接口中添加抽象方法

Cart findByCid(Integer cid);

3 编写映射

在CartMapper文件中添加findByCid(Integer cid)方法的映射

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

4 单元测试

在CartMapperTests测试类中添加findByCid()测试方法

@Test
public void findByCid() {System.out.println(cartMapper.findByCid(1));
}

2.业务层[service]

1规划异常

  • 在更新时产生UpdateException未知异常,此异常类无需再次创建
  • 可能该购物车列表数据归属不是登录的用户,抛AccessDeniedException异常,此异常类无需再次创建
  • 要查询的数据不存在.抛出CartNotFoundException异常,创建该异常类并使其继承ServiceException
/** 购物车数据不存在的异常 */
public class CartNotFoundException extends ServiceException {/**重写ServiceException的所有构造方法*/
}

2设计接口和抽象方法及实现

在业务层ICartService接口中添加addNum()抽象方法

1.先判断需要哪些参数,该抽象方法的实现依赖于CartMapper接口的两个方法:

updateNumByCid方法.参数是cid,num,String modifiedUser,Date modifiedTime

findByCid方法.参数是cid

在业务层中从购物车表查询到该商品的数量,然后再和前端传过来的增加的数量进行求和得到num

所以该方法的参数是cid,uid,username

2.判断一下该方法的返回值:

  • 该方法返回值void.这样的话就需要在前端页面加location.href使该页面自己跳转到自己,实现刷新页面(不建议,每次都加载整个页面,数据量太大了)
  • 返回值是Integer类型.这样的话就把数据库中更新后的数量层层传给前端,前端接收后填充到控件中就可以了
/**
* 增加用户的购物车中某商品的数量
* @param cid
* @param uid
* @param username
* @return 增加成功后新的数量
*/
Integer addNum(Integer cid,Integer uid, String username);

3.在CartServiceImpl类中实现接口中的抽象方法

    /***  更新用户的购物车数量的数据** 调用了updateNumByCid(cid,num,modifiedUser,modifiedTime)*      和findByCid(cid)*  Integer:返回的是最新的购物车数量*/@Overridepublic Integer addNum(Integer cid, Integer uid, String username) {Cart result = cartMapper.findByCid(cid);if(result == null) {throw new CartNotFoundException("购物车数据不存在");} else if(! result.getUid().equals(uid)) {throw new AccessDeniedException("数据非法访问");}Integer num = result.getNum() + 1;Integer rows = cartMapper.updateNumByCid(cid, num, username, new Date());if(rows != 1) {throw new UpdateException("更新数据失败");}return num;}

3单元测试

就接收个参数,然后业务层将其加一后返回,不需要再测了

3.控制层[Controller]

1处理异常

在BaseController类中添加CartNotFoundException异常类的统一管理

else if (e instanceof CartNotFoundException) {result.setState(4007);result.setMessage("购物车表不存在该商品的异常");
}

2设计请求

  • /carts/{cid}/num/add
  • post
  • @PathVariable(“cid”) Integer cid, HttpSession session
  • JsonResult<Integer>

3处理请求

在CartController类中添加处理请求的addNum()方法

    @PostMapping("/{cid}/add_num")public JsonResult<Integer> addNum(@PathVariable("cid") Integer cid,HttpSession session){Integer data = cartService.addNum(cid,getuidFromSession(session),getUsernameFromSession(session));return new JsonResult<>(OK,data);}

4.前端页面

1.首先确定在showCartList()函数中动态拼接的增加购物车按钮是绑定了addNum()事件,如果已经添加无需重复添加

<input class="num-btn" type="button" value="+" onclick="addNum(#{cid})" />

2.在script标签中定义addNum()函数并编写增加购物车数量的逻辑代码

//添加商品按钮function addNum(cid){$.ajax({url:"/cart/"+cid+"/add_num",type: "POST",dataType:"JSON",success(e){console.log(e.state)if (e.state==200){//<input id="goodsCount#{cid}" type="text" size="2" readonly="readonly" class="num-text" value="#{num}">//修改商品数量,// val(): 因为这里使用val,是为了修改value的值$("#goodsCount" + cid).val(e.data);//<td>¥<span id="goodsPrice#{cid}">#{singlePrice}</span></td>//商品单价//html():选中所选元素的html,可能有html元素let singlePrice=$("#goodsPrice"+cid).html();let totalPrice=singlePrice*e.data;//表示将总数加入页面中//<td><span id="goodsCast#{cid}">#{totalPrice}</span></td>$("#goodsCast"+cid).html(totalPrice);}else{alert("增加购物车数据失败"+e.message)}},error(xhr){alert("增加购物车商品数据加载产生未知的异常"+xhr.status)}})}

1.持久层[Mapper]

1.规划需要执行的SQL语句

1.判断当前要删除的商品是否还存在[原来的findById]

selct * from t_cart where uid=? and cid=?

2.如果该商品在该用户的购物车中本来就有,则对其的操作是进行数据更新[原来的updateNumByCid]

2.接口和抽象方法

1.在CartMapper.java

    /*** 修改购物车数据中商品的数量* @param cid 购物车数据的id* @param num 新的数量* @param modifiedUser 修改执行人* @param modifiedTime 修改时间* @return 受影响的行数*/Integer updateNumByCid(@Param("cid") Integer cid,@Param("num") Integer num,@Param("modifiedUser") String modifiedUser,@Param("modifiedTime") Date modifiedTime);/*** 根据用户id和商品id查询购物车中的数据* @param uid 用户id* @param pid 商品id* @return 匹配的购物车数据,如果该用户的购物车中并没有该商品,则返回null*/Cart findByUidAndPid(@Param("uid") Integer uid,@Param("pid") Integer pid);

3.编写映射

    <!-- 修改购物车数据中商品的数量--><update id="updateNumByCid">update t_cart setnum=#{num},modified_user=#{modifiedUser},modified_time=#{modifiedTime}where cid=#{cid}</update><!-- 根据用户id和商品id查询购物车中的数据--><select id="findByUidAndPid" resultMap="CartEntityMap">select * from t_cart where uid=#{uid} AND pid=#{pid}</select>

4.测试代码

此测试代码可以省略

2.业务层[Service]

1.规划异常

  • 在删除的时候,可能该数据被删除,造成删除异常
  • 在更新时产生UpdateException未知异常,此异常类无需再次创建
  • 可能该购物车列表数据归属不是登录的用户,抛AccessDeniedException异常,此异常类无需再次创建
  • 要查询的数据不存在.抛出CartNotFoundException异常,创建该异常类并使其继承ServiceException

2.设计接口和抽象方法的实现

1.ICartService

    /*** 更新用户的购物车数据--减少* @param cid* @param uid* @param username* @return*/Integer subNum(Integer cid,Integer uid,String username);

2.ICartServiceImpl

    /*** 更新用户的购物车数据--减少* @param cid* @param uid* @param username* @return*/@Overridepublic Integer subNum(Integer cid, Integer uid, String username) {Cart result = cartMapper.findByCid(cid);if(result==null){throw new CartNotFoundException("购物车数据不存在");}if(!result.getUid().equals(uid)){throw new AccessDeniedException("数据非法访问");}Integer num=result.getNum()-1;Integer rows = cartMapper.updateNumByCid(cid, num, username, new Date());if(rows!=1){throw new UpdateException("更新数据失败");}return num;}

3.单元测试

    @Testpublic void subNum(){cartService.subNum(3,7,"管理员");}

3.控制层[Controller]

1.处理异常

前面增加功能已经实现,不用重复执行

2.设计请求

  • /cart/sub_num/{cid}
  • post
  • @PathVariable("cid") Integer cid,HttpSession session
  • JsonResult<Integer>

3.处理请求

    /*** 在购物车列表中减少商品数量* @param cid* @param session* @return*/@PostMapping("/sub_num/{cid}")public JsonResult<Integer> subNum(@PathVariable("cid") Integer cid,HttpSession session){Integer data = cartService.subNum(cid,getuidFromSession(session),getUsernameFromSession(session));return new JsonResult<>(OK,data);}

4.前端页面

1.首先确定在showCartList()函数中动态拼接的增加购物车按钮是绑定了reduceNum()事件,如果已经添加无需重复添加

<input id="price-#{cid}"  type="button" value="-" class="num-btn" onclick="reduceNum(#{cid})" />

function reduceNum(cid) {$.ajax({url: "/cart/sub_num/"+cid,type: "POST",dataType: "JSON",success: function(json) {if (json.state == 200) {// showCartList();$("#goodsCount" + cid).val(json.data);let price = $("#goodsPrice" + cid).html();let totalPrice = price * json.data;$("#goodsCast" + cid).html(totalPrice);} else {alert("修改商品数量失败!" + json.message);}},error: function(xhr) {alert("您的登录信息已经过期,请重新登录!HTTP响应码:" + xhr.status);location.href = "login.html";}});}

相关文章:

SpringBoot项目--电脑商城【增加/减少购物车商品数量】

1.持久层[Mapper] 1.1规划需要执行的SQL语句 1.更新该商品的数量.此SQL语句无需重复开发 update t_cart set num?,modified_user?,modified_time? where cid? 2.首先进行查询需要操作的购物车数据信息【查看该条数据是否存在】 SELECT * FROM t_cart WHERE cid?2.接口…...

CSS元素浮动

概述 浮动简介 在最初&#xff0c;浮动是用来实现文字环绕图片效果的&#xff0c;现在浮动是主流的页面布局方式之一。 元素浮动后的特点 脱离文档流。不管浮动前是什么元素&#xff0c;浮动后&#xff0c;默认宽与高都是被内容撑开的&#xff08;尽可能小&#xff09;&am…...

MATLAB中islocalmin函数用法

目录 语法 说明 示例 向量中的局部最小值 矩阵行中的最小值 相隔最小值 最小值平台区 突出最小值 islocalmin函数的功能是计算局部最小值。 语法 TF islocalmin(A) TF islocalmin(A,dim) TF islocalmin(___,Name,Value) [TF,P] islocalmin(___) 说明 ​当在 A 的…...

Python+Requests+Pytest+YAML+Allure实现接口自动化

本项目实现接口自动化的技术选型&#xff1a;PythonRequestsPytestYAMLAllure &#xff0c;主要是针对之前开发的一个接口项目来进行学习&#xff0c;通过 PythonRequests 来发送和处理HTTP协议的请求接口&#xff0c;使用 Pytest 作为测试执行器&#xff0c;使用 YAML 来管理测…...

双视觉Transformer(Dual Vision Transformer)

摘要 已经提出了几种策略来减轻具有高分辨率输入的自注意机制的计算&#xff1a;比如将图像补丁上的全局自注意过程分解成区域和局部特征提取过程&#xff0c;每个过程都招致较小的计算复杂度。尽管效率良好&#xff0c;这些方法很少探索所有补丁之间的整体交互&#xff0c;因…...

MES系统成为工业4.0首选,制造业真正数字化车间你看过吗?

在日益激烈的市场竞争中&#xff0c;MES管理系统已经成为企业提升生产效率、降低成本、提高竞争力的关键。通过MES管理系统实现数据集成和分析&#xff0c;能够对产品制造过程的各个环节进行可视化控制&#xff0c;从设计、制造、质量、物流等环节全面掌控信息&#xff0c;实现…...

Vuex有几种属性以及它们的意义

有五种&#xff0c;分别是 State、 Getter、Mutation 、Action、 Module。 一、State Vuex 使用单一状态树——是的&#xff0c;用一个对象就包含了全部的应用层级状态。至此它便作为一个“唯一数据源 (SSOT)”而存在。这也意味着&#xff0c;每个应用将仅仅包含一个 store 实…...

PRBP20P-10/250C-EB、PRDP6G-10/30-CB电液比例直动式先导减压阀放大板

PRDP6P-10/30-CB、PRDP6R-10/50-DC、PRDP6G-10/30-CC、PRDP6P-10/50-CB、PRDP6R-10/30-CC、PRDP6G-10/30-CB电液比例直动式先导减压阀 PRBP10P-10/50C-EB、PRBP20P-10/100C-EC、PRBP30P-10/150C-EB、PRBP20P-10/250C-EB、PRBP10P-10/315C-EC、PRBP30P-10/350C-EB电液比例柱塞平…...

GDB之常见缩写命令(十九)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…...

MarkText快捷键(随时补充中)

MarkText快捷键 ctrl1&#xff1a;一号标题 &#xff08;需要手动在【左上角】-【file】-【preferences】-【Key Bindings】-【 Transform into Heading 1】手动调整&#xff0c;先将【Switch tab to the 1st】占用快捷键删除才能在下面添加&#xff09; ctrlg&#xff1a;添加…...

每日一题 1601最多可达成的换楼请求数目(子集模版)

题目 1601 我们有 n 栋楼&#xff0c;编号从 0 到 n - 1 。每栋楼有若干员工。由于现在是换楼的季节&#xff0c;部分员工想要换一栋楼居住。 给你一个数组 requests &#xff0c;其中 requests[i] [fromi, toi] &#xff0c;表示一个员工请求从编号为 fromi 的楼搬到编号为…...

排序算法-归并排序

属性 归并排序&#xff08;MERGE-SORT&#xff09;是建立在归并操作上的一种有效的排序算法,该算法是采用分治法&#xff08;Divide and Conquer&#xff09;的一个非常典型的应用。将已有序的子序列合并&#xff0c;得到完全有序的序列&#xff1b;即先使每个子序列有序&#…...

vue3 整合 springboot 打完整jar包

前端 .env.developmen VITE_APP_BASE_URL/api.env.production VITE_APP_BASE_URL/axios 配置 axios.defaults.baseURL import.meta.env.VITE_APP_BASE_URLpackage.json "scripts": {"dev": "vite --mode development","build": &…...

依赖倒转原则是什么?

依赖倒转原则&#xff08;Dependency Inversion Principle&#xff09;是面向对象设计中的另一个基本原则&#xff0c;它是由Robert C. Martin提出的&#xff0c;它的中心思想是面向接口编程&#xff0c;该原则指出高层模块不应该依赖于低层模块&#xff0c;两者都应该依赖于抽…...

什么是GPT与MBR

GPT&#xff08;GUID Partition Table&#xff09;和MBR&#xff08;Master Boot Record&#xff09;是两种不同的磁盘分区表格式。 MBR是一种较早的磁盘分区表格式&#xff0c;它使用512字节的扇区作为存储空间。MBR分区表可以定义最多4个主分区&#xff0c;每个主分区都可以…...

前后端开发接口联调对接参数

前言 一个完整的互联网系统项目,需要前后端配合,进行上线,针对前端开发者,现在互联网主流的项目都是前后端分离 也就是后端负责提供数据接口,前端负责UI界面数据渲染 凡是在前台数据展示与用户交互的,都是由前端来实现的,而数据来源是由后台服务提供的 在浏览器c端能够发送后端…...

定时任务框架-xxljob

1.定时任务 spring传统的定时任务Scheduled&#xff0c;但是这样存在这一些问题 &#xff1a; 做集群任务的重复执行问题 cron表达式定义在代码之中&#xff0c;修改不方便 定时任务失败了&#xff0c;无法重试也没有统计 如果任务量过大&#xff0c;不能有效的分片执行 …...

idea项目配置三大步

场景&#xff1a; 使用 idea 打开一个新项目的时候&#xff0c;想让项目迅速跑起来&#xff0c; 其实只需要下面简单三步&#xff1a; 1. 首先&#xff0c;配maven 2. 其次&#xff0c;配置 jdk 这里配置 project 就行了&#xff0c;不用管Modules中的配置。 3. 最后&#…...

学会SpringMVC之自定义注解各种场景应用,提高开发效率及代码质量

目录 一、简介 ( 1 ) 是什么 ( 2 ) 分类 ( 3 ) 作用 二、自定义注解 ( 1 ) 如何自定义注解 ( 2 ) 场景演示 场景一&#xff08;获取类与方法上的注解值&#xff09; 场景二&#xff08; 获取类属性上的注解属性值 &#xff09; 场景三&#xff08; 获取参数修…...

步态识别常见模块解读及代码实现:基于OpenGait框架

步态识别常见模块解读及代码实现&#xff1a;基于OpenGait框架 最近在看步态识别相关论文&#xff0c;但是因为记忆力下降的原因&#xff0c;老是忘记一些内容。因此记录下来方便以后查阅&#xff0c;仅供自己学习参考&#xff0c;没有背景知识和论文介绍。 目录 步态识别常见…...

前端八股文之“闭包”

一、定义 一句话概括闭包&#xff1a;能够访问函数内部变量的函数与这个变量的组合构成了闭包结构。如下代码 function fuc1(){let num 999return function fuc2(){console.log(num)}}fuc1()(); 如代码所示&#xff0c;fuc2和父级变量num构成了一个闭包环境。 二、原理 子…...

数据可视化:掌握数据领域的万金油技能

⭐️⭐️⭐️⭐️⭐️欢迎来到我的博客⭐️⭐️⭐️⭐️⭐️ 🐴作者:秋无之地 🐴简介:CSDN爬虫、后端、大数据领域创作者。目前从事python爬虫、后端和大数据等相关工作,主要擅长领域有:爬虫、后端、大数据开发、数据分析等。 🐴欢迎小伙伴们点赞👍🏻、收藏⭐️、…...

Apache Kafka 基于 S3 的数据导出、导入、备份、还原、迁移方案

在系统升级或迁移时&#xff0c;用户常常需要将一个 Kafka 集群中的数据导出&#xff08;备份&#xff09;&#xff0c;然后在新集群或另一个集群中再将数据导入&#xff08;还原&#xff09;。通常&#xff0c;Kafka集群间的数据复制和同步多采用 Kafka MirrorMaker&#xff0…...

事务管理AOP

事务管理 事务回顾 概念&#xff1a;事务是一组操作的集合&#xff0c;它是一个不可分割的工作单位&#xff0c;这些操作要么同时成功&#xff0c;要么同时失败 操作&#xff1a; 开启事务&#xff1a;一组操作开始前&#xff0c;开启事务&#xff0d;start transaction/be…...

Java从Tif中抽取最大的那张图进行裁剪成x*y份

之前我有一篇帖子《kfb格式文件转jpg格式》讲述到 kfb > tif > jpg&#xff0c;但是针对于超大tif中的大图是无法顺利提取的&#xff0c;就算是能顺利提取&#xff0c;试想一下&#xff0c;2G的tif文件&#xff0c;如果能提取处理最大的那张图&#xff0c;并且在不压缩的…...

人工智能AI界的龙头企业,炸裂的“英伟达”时代能走多远

原创 | 文 BFT机器人 1、AI芯片的竞争格局已趋白热化 尽管各类具有不同功能和定位的AI芯片在一定程度上可实现互补&#xff0c;但同时也在机遇与挑战并存中持续调整定位。在AI训练端&#xff0c;英伟达的GPU凭着高算力的门槛&#xff0c;一直都是训练端的首选。 只有少数芯片能…...

【实战】H5 页面同时适配 PC 移动端 —— 旋转横屏

文章目录 一、场景二、方案三、书单推荐01 《深入实践Kotlin元编程》02 《Spring Boot学习指南》03 《Kotlin编程实战》 一、场景 一个做数据监控的单页面&#xff0c;页面主要内容是一个整体必须是宽屏才能正常展示&#xff0c;这时就不能用传统的适配方案了&#xff0c;需要…...

使用凌鲨进行聚合搜索

作为研发人员&#xff0c;我们经常需要在多个来源之间查找信息&#xff0c;以便进行研发工作。除了常用的搜索引擎如百度和必应之外&#xff0c;我们还需要查阅各种代码文档和依赖包等资源。这些资源通常分散在各个网站和文档库中&#xff0c;需要花费一定的时间和精力才能找到…...

程序设计之——手把手教你如何从Excel文件中读取学生信息

在当今信息化时代&#xff0c;计算机技术已经深入到各个领域&#xff0c;而程序设计则成为推动信息化建设的关键技术之一。在众多领域中&#xff0c;学生信息管理系统无疑是其中一个重要的应用。本文将从学生信息管理系统的开发入手&#xff0c;探讨开如何高效且保证质量的完成…...

Docker容器化技术(从零学会Docker)

文章目录 前言一、初识Docker1.初识Docker-Docker概述2.初识Docker-安装Docker3.初识Docker-Docker架构4.初识Docker-配置镜像加速器 二、Docker命令1.Docker命令-服务相关命令2.Docker命令-镜像相关命令3.Docker命令-容器相关命令 三、Docker容器的数据卷1.Docker容器数据卷-数…...

jquery代码做的网站/计算机培训

今天在往本地导数据表的时候老是报错&#xff1a; [Err] 1294 - Invalid ON UPDATE clause for 字段名 column 报错的数据表字段&#xff1a; 字段名 datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP 同事说同一个 sql 文件他可以导成功。猜可能是数据库版本的问题&#xf…...

用html5的视频网站/河南网站建站推广

博士复试英文自我介绍范文.doc (2页)本资源提供全文预览&#xff0c;点击全文预览即可全文预览,如果喜欢文档就下载吧&#xff0c;查找使用更方便哦&#xff01;7.90 积分&#xfeff;博士复试英文自我介绍范文   博士复试英文自我介绍&#xff1a;  Good afternoon,profes…...

网站建设流程服务/营销必备十大软件

简介 一个很方便的用来在JS中控制元素类的方法&#xff0c;完全可以取代jQuery中对class的操作 classList属性返回元素的类名&#xff0c;作为DOMTokenList对象。该属性用于在元素中添加&#xff0c;移除及切换 CSS 类。 classList属性是只读的&#xff0c;但你可以使用add(…...

淘宝导购网站怎么做/嵌入式培训班一般多少钱

Python中可以很方便的利用切片来复制列表&#xff0c;但有个误区容易使初学者犯错误&#xff0c;即切片复制列表。 book [a,b,c,d] #将book列表中的a、b、c复制到itbook中 itBook book[0:2] print(book) print(itBook)#将book关联到itbook1&#xff0c;两者指向同一个列表 i…...

湖南营销型网站建设 地址磐石网络/seo优化招聘

一、选择题及参考答案1、请问以下关于在方法中定义的内部类的描述正确的有&#xff1f;它和所在的外部类的任何实例无关它可以访问所在方法中声明为final的变量它可以被任何一种访问修饰符修饰它不能实现接口答案&#xff1a;AB2、请问以下关于非静态内部类的说法正确的是&…...

做家装的网站有什么/优化设计三要素

依照教程记录 -java https://blog.csdn.net/a360616218/article/details/76736988 -tomcat https://www.cnblogs.com/qianzf/p/6986962.html -svn https://www.cnblogs.com/liuxianan/p/linux_install_svn_server.html 依照教程会出现的问题在于可能没提到防火墙的问题&#xf…...