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

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";}});});

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

相关文章:

  • springboot将文件插入到指定路径文件夹,判断文件是否存在以及根据名称删除
  • 思辨场域丨AR技术如何重塑未来学术会议体验?
  • 绝不强迫登录!Apipost 离线模式正式上线
  • [学习] 在C语言中使用字典(附示例)
  • tkinter Entry(输入框)组件学习指南
  • Ajax-入门
  • React Native【详解】动画
  • 小白的进阶之路系列之十七----人工智能从初步到精通pytorch综合运用的讲解第十部分
  • 【unitrix】 3.4 类型级逻辑运算(bit.rs)
  • 【Docker】docker-compose中的nginx为何突然访问不到服务了?
  • 【CS创世SD NAND征文】STM32户外无线终端管理设备的数据存储方案
  • 拼多多消息对接、支付服务策略(策略+工厂)
  • supervisor /usr/bin/dotnet: cannot execute binary file
  • cili3d笔记20 正交投影3d重建笔记1
  • GoFrame的Gtoken--基于电商项目以及GPT-o3的辅助解惑
  • 如何轻松地将联系人从 iPhone 转移到 iPhone?
  • window显示驱动开发—输出合并器阶段
  • django FileSystemStorage is located outside of the base path component
  • 【前端隐蔽 Bug 深度剖析:SVG 组件复用中的 ID 冲突陷阱】
  • QT的一些介绍
  • wordpress 速度/北京seo
  • 网站如何建设与安全/磐石网站seo
  • 政府网站建设排名/潍坊百度关键词优化
  • dede模板蓝色大气简洁企业网站模板/铜川网络推广
  • 海尔网站建设的目标是什么/网络推广产品公司
  • 嘉兴企业做网站/seo就业指导