SpringBoot电脑商城项目--商品详情+加入购物车

商品详情

1. 持久层

1.1. 规划sql语句

        根据id查询商品详情

1.2 mapper层编写抽象方法

    /*** 根据商品id查询商品详情* @param id 商品id* @return 匹配的id商品详情,如果没有匹配的数据,则返回null*/Product findById(Integer id);

1.3 xml文件中编写sql映射

        查到的数据要封装成resultMap结果集

    <select id="findById" resultMap="ProductEntityMap">select * from t_product where id=#{id}</select>

2. 业务层

2.1 规划异常

        根据id查询商品信息时可能会出现找不到的异常,需要定义一个ProductNotFoundException类

package com.cy.store.service.ex;/** 商品数据不存在的异常 */
public class ProductNotFoundException extends ServiceException {public ProductNotFoundException() {super();}public ProductNotFoundException(String message) {super(message);}public ProductNotFoundException(String message, Throwable cause) {super(message, cause);}public ProductNotFoundException(Throwable cause) {super(cause);}protected ProductNotFoundException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {super(message, cause, enableSuppression, writableStackTrace);}
}

2.2 在Service类编写接口和抽象方法

    /** 根据商品id查询商品详情 */Product findById(Integer id);

2.3 实现类实现接口重写抽象方法

    /*** 根据商品id查询商品详情* @param id 商品id* @return 匹配的id商品详情,如果没有匹配的数据,则返回null*/@Overridepublic Product findById(Integer id) {Product product = productMapper.findById(id);// 判断查询结果是否为nullif (product == null) {throw new ProductNotFoundException("尝试访问的商品数据不存在");}// 将查询结果中的部分属性设置为nullproduct.setPriority(null);product.setCreatedUser(null);product.setCreatedTime(null);product.setModifiedUser(null);product.setModifiedTime(null);return product;}

3. 控制层

3.1 捕获异常

        在BaseController中捕获ProductNotFoundException异常

else if (e instanceof ProductNotFoundException){result.setState(4006);result.setMessage("商品数据不存在");}

3.2 controller实现请求

    /*** 获取商品详情* @param id 商品id* @return 商品详情*/@RequestMapping("/details/{id}")public JsonResult<Product> getById(@PathVariable("id") Integer id){Product data = productService.findById(id);return new JsonResult<>(OK,data);}

4. 前端页面

        product.html页面

		<!-- 引入用于获取URL参数的jQuery插件,以便后续JS代码中获取商品ID --><script type="text/javascript" src="../js/jquery-getUrlParam.js"></script><script type="text/javascript">// 文档加载完成后执行以下代码$(document).ready(function () {// 使用 jQuery 插件 getUrlParam 获取 URL 中的 "id" 参数值,即商品IDvar id = $.getUrlParam("id");console.log("id=" + id);// 发起 AJAX 请求获取该商品的详细信息$.ajax({url: "/products/details/"+ id, // 请求地址type: "GET", // 请求方法为 GETsuccess: function (json) { // 请求成功时的回调函数if (json.state == 200) { // 如果返回状态码为 200,表示请求成功console.log("title=" + json.data.title);// 将商品标题、卖点、价格填充到页面对应元素中$("#product-title").html(json.data.title);$("#product-sell-point").html(json.data.sellPoint);$("#product-price").html(json.data.price);// 循环更新5张商品图片的路径(大图和缩略图)for (var i = 1; i <= 5; i++) {$("#product-image-" + i + "-big").attr("src", ".." + json.data.image + i + "_big.png");$("#product-image-" + i).attr("src", ".." + json.data.image + i + ".jpg");}} else if (json.state == 4006) { // 如果商品数据不存在,则跳转回首页location.href = "index.html";} else { // 其他错误情况弹出提示信息alert("获取商品信息失败!" + json.message);}}});});</script>

加入购物车

1. 在数据库中创建购物车的表(t_cart)

CREATE TABLE t_cart (cid INT AUTO_INCREMENT COMMENT '购物车数据id',uid INT NOT NULL COMMENT '用户id',pid INT NOT NULL COMMENT '商品id',price BIGINT COMMENT '加入时商品单价',num INT COMMENT '商品数量',created_user VARCHAR(20) COMMENT '创建人',created_time DATETIME COMMENT '创建时间',modified_user VARCHAR(20) COMMENT '修改人',modified_time DATETIME COMMENT '修改时间',PRIMARY KEY (cid)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

2. 创建Cart实体类

        @Data:是Lombok提供的注解,自动生成类的getter、setter、toString等方法

package com.cy.store.entity;import lombok.Data;/**购物车数据的实体类*/
@Data
public class Cart extends BaseEntity {private Integer cid;private Integer uid;private Integer pid;private Long price;private Integer num;
}

3. 持久层

3.1 规划sql语句

  • 向购物车表中插入数据

insert into t_cart () value()

  • 如果当前商品已经存在与购物车中,则直接更新数量num就行

update t_cart set
            num=#{num},
            modified_user=#{modifiedUser},
            modified_time=#{modifiedTime}
        where cid=#{cid}

  • 在插入或者更新具体执行哪个语句,取决于数据库中是否有当前这个购物车商品的数量,得去查询才能确定

select * from t_cart where uid=#{uid} AND pid=#{pid}

3.2 创建CartMapper接口,编写抽象方法

@Mapper
public interface CartMapper {/*** 插入购物车数据* @param cart 购物车数据* @return 受影响的行数*/Integer insert(Cart cart);/*** 根据用户id和商品id修改购物车数据* @param cid 购物车id* @param num 修改之后的数量* @param modifiedUser 修改执行人* @param modifiedTime 修改时间* @return*/Integer updateNumByCid(Integer cid,Integer num,String modifiedUser,Date modifiedTime);/*** 根据用户id和商品id查询购物车数据* @param uid 用户id* @param pid 商品id* @return 匹配的购物车数据,如果没有匹配的数据则返回null*/Cart findByUidAndPid(Integer uid, Integer pid);}

3.3 在CartMapper.xml文件中进行sql映射以及sql的编写

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cy.store.mapper.CartMapper"><resultMap id="CartEntityMap" type="com.cy.store.entity.Cart"><id column="cid" property="cid"/><result column="created_user" property="createdUser"/><result column="created_time" property="createdTime"/><result column="modified_user" property="modifiedUser"/><result column="modified_time" property="modifiedTime"/></resultMap><!-- 插入购物车数据--><insert id="insert" useGeneratedKeys="true" keyProperty="cid">insert into t_cart (uid, pid, price, num, created_user, created_time, modified_user, modified_time)values (#{uid}, #{pid}, #{price}, #{num}, #{createdUser}, #{createdTime}, #{modifiedUser}, #{modifiedTime})</insert><!-- 修改购物车数据中商品的数量--><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>
</mapper>

3.4 在CartMapperTest类中进行测试

@SpringBootTest
class CartMapperTest {@Autowiredprivate CartMapper cartMapper;@Testpublic void insert() {Cart cart = new Cart();cart.setUid(1);cart.setPid(2);cart.setNum(2);cart.setPrice(3000l);cart.setCreatedTime(new Date());cart.setModifiedTime(new Date());cart.setCreatedUser("admin1");cart.setModifiedUser("admin1");Integer rows = cartMapper.insert(cart);System.out.println(rows);}@Testpublic void updateNumByCid() {Integer rows = cartMapper.updateNumByCid(1, 2, "admin", new Date());System.out.println(rows);}@Testpublic void findByUidAndPid() {Cart cart = cartMapper.findByUidAndPid(1, 1);System.out.println(cart);}}

4. 业务层

4.1 规划异常

  • 插入数据库购物车数据时可能产生InsertException异常
  • 更新数据时可能出现UpdateException异常

4.2 创建CartService接口类,编写业务层的抽象方法

        更新时间这些字段可以通过new Date()获取,所以CartService接口层只需要用户id,商品id以及数量,更新人这些字段

package com.cy.store.service;public interface CartService {/*** 添加商品到购物车* @param uid 用户id* @param pid 商品id* @param amount 商品数量* @param username 用户名*/void addToCart(Integer uid, Integer pid, Integer amount, String username);}

4.3 实现类实现接口,重写抽象方法

        其中的商品价格可以通过商品表获取,这里需要注入ProductMapper,调用根据pid获取商品价格

@Service
public class CartServiceImpl implements CartService {@Autowiredprivate CartMapper cartMapper;@Autowiredprivate ProductMapper productMapper;/*** 添加购物车* @param uid 用户id* @param pid 商品id* @param amount 商品数量* @param username 用户名*/@Overridepublic void addToCart(Integer uid, Integer pid, Integer amount, String username) {
//        查询当前用户购物车中是否存在此商品Cart res = cartMapper.findByUidAndPid(uid, pid);Date date = new Date();//        不存在的话就添加if (res == null) {
//            补全价格Cart cart = new Cart();cart.setUid(uid);cart.setPid(pid);cart.setNum(amount);
//            获取商品表中商品的价格,封装到cart中Product product = productMapper.findById(pid);cart.setPrice(product.getPrice());cart.setCreatedTime(date);cart.setModifiedTime(date);cart.setCreatedUser( username);cart.setModifiedUser(username);cartMapper.insert(cart);}else {//存在的话就修改购物车中商品的数量
//            商品数量=购物车中的数量+用户传递的数量amount = res.getNum()+amount;Integer integer = cartMapper.updateNumByCid(res.getCid(), amount, username, date);if (integer!=1){throw new UpdateException("更新数据时产生未知的异常");}}}
}

4.4 测试

package com.cy.store.service;import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;@SpringBootTest
class CartServiceTest {@Autowiredprivate CartService cartService;@Testvoid addToCart() {cartService.addToCart(3, 10000001, 10, "admin");}
}

5. 控制层

5.1 设计请求

请求路径:/carts/addToCart

请求方式:GET

请求参数:pid,amount ,session

响应数据:JsonResult<Void>

5.2 实现请求

package com.cy.store.controller;import com.cy.store.service.CartService;
import com.cy.store.util.JsonResult;
import jakarta.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/carts")
public class CartController extends BaseController{@Autowiredprivate CartService cartService;@RequestMapping("addToCart")public JsonResult addToCart(Integer pid, Integer amount, HttpSession session) {Integer uid = getUidFromSession(session);String username = getUsernameFromSession(session);cartService.addToCart( uid,pid, amount, username);return new JsonResult<>(OK);}
}

5.3 启动项目,测试

6. 前端页面

        在product.html页面给【加入购物车】按钮添加点击事件。发送ajax请求

        在ajax函数中data参数的数据设置的方式:

  • data:$("form表单名称").seriallize():当参数过多并且在同一个表单中,字符串的提交时
  • data:new FormData($("form表单名称")[0]):只适用于文件
  • data:"username=Tom":适合于参数值固定并且参数值列表有限,可以进行手动拼接

let user = "admin"

data:"username="+user

  • 使用JSON格式提交数据
data: {"pid": id, // 商品id"amount": $("#num").val() // 监听数量输入框中的值
}

代码如下:

// 点击“加入购物车”按钮时触发 AJAX 请求,将商品加入购物车(当前被注释)$("#btn-add-to-cart").click(function() {$.ajax({url: "/carts/addToCart",type: "POST",// 通过json格式传参data: {"pid": id, // 商品id"amount": $("#num").val() // 监听数量输入框中的值},dataType: "JSON",success: function(json) {if (json.state == 200) {alert("增加成功!");} else {alert("增加失败!" + json.message);}},error: function(xhr) {alert("您的登录信息已经过期,请重新登录!HTTP响应码:" + xhr.status);location.href = "login.html";}});});

        重启项目进行测试,查看数据库是否新增成功

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/86064.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/86064.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

上交卡尔动力联合提出FastDrive!结构化标签实现自动驾驶端到端大模型更快更强

最近将类人的推理能力融入到端到端自动驾驶系统中已经成为了一个前沿的研究领域。其中&#xff0c;基于视觉语言模型的方法已经吸引了来自工业界和学术界的广泛关注。 现有的VLM训练范式严重依赖带有自由格式的文本标注数据集&#xff0c;如图1(a)所示。虽然这些描述能够捕捉丰…

C# 委托(什么是委托)

什么是委托 可以认为委托是持有一个或多个方法的对象。当然&#xff0c;一般情况下你不会想要“执行”一个对 象&#xff0c;但委托与典型的对象不同。可以执行委托&#xff0c;这时委托会执行它所“持有"的方法。 本章将揭示创建和使用委托的语法和语义。在本章后面&am…

iTwin briefcase, checkpoint ,standalone

在 iTwin.js 中&#xff0c;briefcase 和 checkpoint 都是 IModel 的不同连接类型&#xff0c;但它们的用途和特性不同&#xff1a; Briefcase 用途&#xff1a;用于本地编辑和同步。通常是用户从 iModelHub 检出&#xff08;Check-out&#xff09;后在本地生成的可写副本。特…

媒体AI关键技术研究

一、引言 随着人工智能技术的迅猛发展&#xff0c;媒体行业正经历前所未有的变革。AI技术不仅重塑了内容生产和传播模式&#xff0c;更为媒体创意发展提供了全新可能。在数字化、移动化和信息爆炸的大背景下&#xff0c;传统媒体面临巨大挑战&#xff0c;而AI技术为行业带来了…

Cargo 与 Rust 项目

一、Rust 项目&#xff1a;现代化的系统编程单元 Rust 项目 是用 Rust 语言编写的软件工程单元&#xff0c;具有以下核心特征&#xff1a; 核心组件&#xff1a; src/ 目录&#xff1a;存放 Rust 源代码&#xff08;.rs 文件&#xff09; Cargo.toml&#xff1a;项目清单文件…

uni-app总结6-配合iOS App项目开发apple watch app

假设你已经用uni-app开发好了一个iOS端的app,现在想要开发一个配套的apple watch app。改怎么去开发呢?是不是一头雾水,这篇文章就会介绍一些apple watch app开发的知识以及如何在uni-app开发的iOS app基础上去开发配套的watch app。 一、apple watch 开发知识 apple watc…

神经网络的本质 逻辑回归 python的动态展示

神经网络的本质 逻辑回归 python的动态展示 逻辑回归运行图相关代码什么是逻辑回归和ai的关系逻辑回归公式流程与实际案例解析**一、逻辑回归的数学公式流程**1. **线性组合阶段**2. **激活函数&#xff08;Sigmoid&#xff09;**3. **概率预测与决策**4. **交叉熵损失函数**5.…

sql server中的with 锁各种区别

&#x1f4d8; SQL Server 常用 WITH (Hint) 用法与组合场景对照表 Hint 组合作用说明常见用途是否阻塞他人是否读脏数据备注WITH (NOLOCK)不加共享锁&#xff0c;允许读取未提交数据报表导出、大数据分页❌✅等价于 READ UNCOMMITTED&#xff0c;脏读风险高WITH (HOLDLOCK)保持…

KES数据库部署工具使用

一、启动部署工具 Windows系统 #命令行 ${安装目录}/ClientTools/guitools/DeployTools/deploy.exeLinux系统 #命令行 [rootnode ~]# ${安装目录}/ClientTools/guitools/DeployTools/deploy二、环境配置 1.硬件要求 #都是最小配置 CPU&#xff1a;主流32或64位 内存&#…

TB62211FNG是一款采用时钟输入控制的PWM斩波器的两相双极步进电机驱动器

TB62211FNG是一款采用时钟输入控制的PWM斩波器的两相双极步进电机驱动器。该器件采用BiCD工艺制造&#xff0c;额定电压为40伏/1.0安培。片上电压调节器允许使用单一VM电源控制步进电机。 特点&#xff1a; • 双极性步进电机驱动器 • 脉冲宽度调制&#xff08;PWM&#xf…

uni-app项目实战笔记24--uniapp实现图片保存到手机相册

前提条件&#xff1a;微信小程序要想实现保存图片到本地相册需要到微信公众平台--小程序--开发管理中配置服务器域名中的downloadFile合法域名&#xff1a; \uniapp提供了saveImageToPhotosAlbum API实现保存的图片到本地相册。下面是它的配置参数&#xff1a; 参数名类型必填…

面试题-定义一个函数入参数是any类型,返回值是string类型,如何写出这个函数,代码示例

在 TypeScript 里&#xff0c;要定义一个入参为any类型、返回值为string类型的函数&#xff0c;可参考下面几种实现方式&#xff1a; 1. 基础实现 直接把入参转换为字符串返回。 function anyToString(input: any): string {return String(input); // 使用String()进行类型转…

TensorFlow深度学习实战——Transformer模型评价指标

TensorFlow深度学习实战——Transformer模型评价指标 0. 前言1. 质量1.1 GLUE1.2 SuperGLUE1.3 SQuAD1.4 RACE1.5 NLP-progress2. 参数规模3. 服务成本相关链接0. 前言 可以使用多种类型的指标评估 Transformer 模型。在本节中,我们将学习一些用于评估 Transformer 的关键因素…

linux内核学习(一)---内核社区介绍及补丁提交

目录 一、引言 二、内核源码 三、内核社区 ------>3.1、社区的组织架构 ------>3.2、内核社区的工作方式 ------>3.3、内核社区核心网站 ------------>3.3.1、Linux Kernel 官网 ------------>3.3.2、Linux Kernel 邮件列表(LKML) ------------>3.3…

轻量级web开发框架之Flask web开发框架学习:get请求数据的发送

Flask是一个使用 Python 编写的轻量级 Web 应用框架&#xff0c;简介灵活&#xff0c;可快速构建开发框架。 协作流程示例 客户端请求 → Web服务器&#xff08;Nginx&#xff09; → WSGI服务器&#xff08;Gunicorn/uWSGI&#xff09;↓WSGI协议传递请求数据&#xff08;env…

Vue 3 异步三剑客:Suspense、async setup() 和 await 的戏剧性关系,白屏的解决

文章目录 &#x1f3ad; Vue 3 异步三剑客&#xff1a;Suspense、async setup() 和 await 的戏剧性关系&#xff0c;白屏的解决&#x1f3ac; 角色介绍&#x1f3ad; 正常演出流程&#xff08;有 Suspense 时&#xff09;&#x1f4a5; 灾难场景&#xff08;缺少 Suspense 时&a…

【JavaScript-Day 48】告别 Ajax,拥抱现代网络请求:Fetch API 完全指南

Langchain系列文章目录 01-玩转LangChain&#xff1a;从模型调用到Prompt模板与输出解析的完整指南 02-玩转 LangChain Memory 模块&#xff1a;四种记忆类型详解及应用场景全覆盖 03-全面掌握 LangChain&#xff1a;从核心链条构建到动态任务分配的实战指南 04-玩转 LangChai…

BUUCTF在线评测-练习场-WebCTF习题[极客大挑战 2019]Knife1-flag获取、解析

解题思路 这题没有什么解题思路&#xff0c;打开靶场&#xff0c;标题是白给的shell 页面显示了 eval($_POST["Syc"]); 这是php webshell命令&#xff0c;密码为Syc&#xff0c;可直接通过该命令连接&#xff0c;根据标题提示&#xff0c;直接尝试用蚁剑连接 连接成…

Qt—(Qt线程,Qt进程,,QT与sqlite数据库)

一 Qt线程与进程概述 线程与进程对比 特性线程 (QThread)进程 (QProcess)内存空间共享父进程内存独立内存空间创建开销小 (几MB)大 (几十MB)通信方式共享内存/信号槽管道/套接字/文件崩溃影响导致整个进程终止仅自身终止适用场景高并发任务、计算密集型隔离第三方应用、安全需求…

计算机视觉阶段一:CV入门基础

目录 学习目标&#xff1a; 一、核心知识点 二、实用工具推荐 三、学习内容与步骤 1.环境搭建 2.图像获取与显示 3 图像基础处理 4 图像几何变换 5 图像像素操作 四、实战任务建议 实战 1&#xff1a;图像加载 显示 保存 实战 2&#xff1a;灰度图 边缘检测 图…