首页 > 分享 > 10天手敲一个SpringBoot网上商城项目(七)——显示商品详情功能及加入购物车功能的实现

10天手敲一个SpringBoot网上商城项目(七)——显示商品详情功能及加入购物车功能的实现

静态资源及sql文件分享
链接:https://pan.baidu.com/s/1X-yjmQcPD3PqS21x0HplNA?pwd=23gr
提取码:23gr

文章目录 显示商品详情1.显示商品详情-持久层1.1规划需要执行的SQL语句1.2设计接口和抽象方法1.3编写映射 2.显示商品详情-业务层2.1规划异常2.2设计接口和抽象方法及实现 3.显示商品详情-控制层3.1处理异常3.2 设计请求3.3处理请求 4.显示商品详情-前端页面 加入购物车1.创建数据表2.创建购物车的实体类3.加入购物车-持久层3.1规划需要执行的SQL语句3.2设计接口和抽象方法3.3编写映射3.4单元测试 4.加入购物车-业务层4.1规划异常4.2设计接口和抽象方法及实现4.3单元测试 5.加入购物车-控制层5.1处理异常5.2设计请求5.3处理请求 6.加入购物车-前端页面

显示商品详情

1.显示商品详情-持久层 1.1规划需要执行的SQL语句

根据商品id显示商品详情的SQL语句

SELECT * FROM t_product WHERE id=? 1 1.2设计接口和抽象方法

在ProductMapper接口中添加抽象方法

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

在ProductMapper.xml文件中配置findById(Integer id)方法的映射

<select id="findById" resultMap="ProductEntityMap"> select * from t_product where id=#{id} </select> 123 2.显示商品详情-业务层 2.1规划异常

如果商品数据不存在,应该抛出ProductNotFoundException,所以创建ProductNotFoundException异常类并使其继承ServiceException

/** 商品数据不存在的异常 */ public class ProductNotFoundException extends ServiceException { /**重写ServiceException的所有构造方法*/ } 1234 2.2设计接口和抽象方法及实现

1.在业务层IProductService接口中添加findById(Integer id)抽象方法

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

2.在ProductServiceImpl类中,实现接口中的findById(Integer id)抽象方法

@Override public Product findById(Integer id) { Product product = productMapper.findById(id); // 判断查询结果是否为null if (product == null) { throw new ProductNotFoundException("尝试访问的商品数据不存在"); } // 将查询结果中的部分属性设置为null product.setPriority(null); product.setCreatedUser(null); product.setCreatedTime(null); product.setModifiedUser(null); product.setModifiedTime(null); return product; } 12345678910111213141516 3.显示商品详情-控制层 3.1处理异常

在BaseController类中的handleException()方法中添加处理ProductNotFoundException的异常

else if (e instanceof ProductNotFoundException) {result.setState(4006); result.setMessage("访问的商品数据不存在的异常"); } 1234 3.2 设计请求 /products/{id}/detailsInteger idGETJsonResult<Product> 3.3处理请求

在ProductController类中添加处理请求的getById()方法

@GetMapping("{id}/details") public JsonResult<Product> getById(@PathVariable("id") Integer id) { Product data = productService.findById(id); return new JsonResult<Product>(OK, data); } 12345 4.显示商品详情-前端页面

1.首页将商品id发送给详情页后,详情页需要从url中裁取获得该id,实现方法在jquery-getUrlParam.js中(目前怎么实现裁取可以先不学),所以需要在product.html页面中导入该js文件,这里我在body标签内部的最后引入该js文件

<script type="text/javascript" src="../js/jquery-getUrlParam.js"></script> 1

2.在product.html页面中body标签内部的最后添加获取当前商品详情的代码

<script type="text/javascript"> //调用jquery-getUrlParam.js文件的getUrlParam方法获取商品id var id = $.getUrlParam("id"); console.log("id=" + id); $(document).ready(function() { $.ajax({ url: "/products/" + id + "/details", type: "GET", dataType: "JSON", success: function(json) { if (json.state == 200) { console.log("title=" + json.data.title); //html()方法: // 假设有个标签<div id="a"></div> //那么$("#a").html(<p></p>)就是给该div标签加p标签 //$("#a").html("我爱中国")就是给该div标签填充"我爱中国"内容 $("#product-title").html(json.data.title); $("#product-sell-point").html(json.data.sellPoint); $("#product-price").html(json.data.price); 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> 123456789101112131415161718192021222324252627282930313233

加入购物车

1.创建数据表

1.使用use命令先选中store数据库

USE store; 1

2.在store数据库中创建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; 123456789101112 2.创建购物车的实体类

在entity包下创建购物车的Cart实体类并使其继承BaseEntity

/**购物车数据的实体类*/ public class Cart extends BaseEntity { private Integer cid; private Integer uid; private Integer pid; private Long price; private Integer num; /** * get,set * equals和hashCode * toString */ } 12345678910111213 3.加入购物车-持久层 3.1规划需要执行的SQL语句

1.向购物车表中插入商品数据的SQL语句

insert into t_cart (除了cid以外的所有字段) values (匹配的值列表); 1

2.如果当前商品已经在购物车存在,则直接更新商品即可

update t_cart set num=? where cid=? 1

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

select * from t_cart where uid=? and pid=? 1 3.2设计接口和抽象方法

在mapper包下创建CartMapper接口,并添加抽象方法

public interface CartMapper { /** * 插入购物车数据 * @param cart 购物车数据 * @return 受影响的行数 */ Integer insert(Cart cart); /** * 修改购物车数据中商品的数量 * @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); } 123456789101112131415161718192021222324252627282930313233 3.3编写映射

在resources.mapper文件夹下创建CartMapper.xml文件,并在文件中配置以上三个方法的映射

<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//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 set num=#{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> 123456789101112131415161718192021222324252627282930313233 3.4单元测试

创建CartMapperTests测试类进行测试

@RunWith(SpringRunner.class) @SpringBootTest public class CartMapperTests { @Autowired private CartMapper cartMapper; @Test public void insert() { Cart cart = new Cart(); cart.setUid(11); cart.setPid(10000001); cart.setNum(3); cart.setPrice(4L);//长整型 cartMapper.insert(cart); } @Test public void updateNumByCid() { cartMapper.updateNumByCid(1, 4, "张三", new Date()); } @Test public void findByUidAndPid() { Cart cart = cartMapper.findByUidAndPid(11, 10000001); System.out.println(cart); } } 123456789101112131415161718192021222324252627 4.加入购物车-业务层 4.1规划异常

在插入数据时,可能抛出InsertException异常;在修改数据时,可能抛出UpdateException异常.这两个异常已开发

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

1.在com.cy.store.service包下创建ICartService接口,并添加抽象方法

该抽象方法都需要哪些参数呢,还是依据持久层,看持久层三条sql语句的实现需要什么参数:

findByUidAndPid:查询购物车数据,参数是uid,pid

insert:插入购物车数据,参数是cart对象(属性有cid,uid,pid,price,num)

updateNumByCid:修改购物车中商品数量,参数是cid,num,modifiedUser,modifiedTime

price可以通过业务层中调用ProductMapper接口的findById获取,modifiedTime在业务层实现类的内部创建,所以需要的参数是uid,pid,num,username

经过这次分析结合以前给业务层方法声明参数,可以发现即使持久层的方法参数是实体类对象,业务层的方法参数也大多不是实体类对象,因为实体类的部分属性是可以在业务层进行拼接然后封装到实体类对象中,再传给持久层(比如这里的price),这样的话就降低了前端传递数据的压力,如果该对象的所有方法都必须由前端传递过来,那么业务层方法参数可以是实体类对象(如注册用户时业务层的方法参数就是User对象)

public interface ICartService { /** * 将商品添加到购物车 * @param uid 当前登录用户的id * @param pid 商品的id * @param amount 增加的数量 * @param username 当前登录的用户名 */ void addToCart(Integer uid, Integer pid, Integer amount, String username); } 12345678910

2.创建CartServiceImpl类,并实现ICartService接口.在类中声明CartMapper持久层对象和IProductService处理商品数据的业务对象,并实现业务层的抽象方法

@Service public class CartServiceImpl implements ICartService { /**购物车的业务层依赖于购物车的持久层以及商品的持久层*/ @Autowired private CartMapper cartMapper; @Autowired private ProductMapper productMapper; @Override public void addToCart(Integer uid, Integer pid, Integer amount, String username) { //根据参数pid和uid查询购物车中该商品是否已经存在 Cart result = cartMapper.findByUidAndPid(uid, pid); Integer cid = result.getCid(); Date date = new Date(); if (result == null) { Cart cart = new Cart(); //封装数据:uid,pid,amount cart.setUid(uid); cart.setPid(pid); cart.setNum(amount);//注意前端传来amount时并没有和数据库商品数量进行求和 //查询商品数据,得到商品价格并封装 Product product = productMapper.findById(pid); cart.setPrice(product.getPrice()); //封装数据:4个日志 cart.setCreatedUser(username); cart.setCreatedTime(date); cart.setModifiedUser(username); cart.setModifiedTime(date); Integer rows = cartMapper.insert(cart); if (rows != 1) { throw new InsertException("插入数据时出现未知异常"); } } else { //从查询结果中取出原数量,与参数amount相加,得到新的数量 Integer num = result.getNum() + amount;//加入购物车时只会有+不可能有- Integer rows = cartMapper.updateNumByCid( result.getCid(), num, username, date); if (rows != 1) { throw new InsertException("更新数据时产生未知异常"); } } } } 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253 4.3单元测试

创建测试类CartServiceTests并编写测试方法。

@RunWith(SpringRunner.class) @SpringBootTest public class CartServiceTests { @Autowired private ICartService cartService; @Test public void addToCart() { cartService.addToCart(11, 10000002, 5, "Tom"); } } 1234567891011 5.加入购物车-控制层 5.1处理异常

InsertException异常和UpdateException异常都已经设置到BaseController类中了,这里无需重复开发

5.2设计请求 /carts/add_to_cartpostInteger pid, Integer amount, HttpSession sessionJsonResult<Void> 5.3处理请求

在controller包下创建CartController类并继承BaseController类,在类中添加处理请求的addToCart()方法

@RestController @RequestMapping("carts") public class CartController extends BaseController { @Autowired private ICartService cartService; @RequestMapping("add_to_cart") public JsonResult<Void> addToCart(Integer pid, Integer amount, HttpSession session) { cartService.addToCart( getUidFromSession(session), pid, amount, getUsernameFromSession(session)); return new JsonResult<Void>(OK); } } 12345678910111213141516

启动服务,登录账号后在地址栏输入http://localhost:8080/carts/add_to_cart?pid=10000002&amount=5进行测试

6.加入购物车-前端页面

在product.html页面中的body标签内的script标签里为“加入购物车”按钮添加点击事件

回顾一下在ajax函数中data参数的数据设置的方式

data:$(“选择的form表单”).serialize()。当需要提交的参数过多并且在同一个表单中时使用

data:new FormData($(“选择的form表单”)[0])。只适用提交文件

data:“username=TOM”。手动拼接,适合参数值固定并且参数值列表有限.等同于

var user = "控件某属性值或控件文本内容或自己声明的值" data: "username="+user 12

使用JSON格式提交数据

data: { "username": "Tom", "age": 18 } 1234

使用RestFul风格不属于前端给后端传参数

这里表单里面有很多无用参数,所以不使用表单提交

$("#btn-add-to-cart").click(function() { $.ajax({ url: "/carts/add_to_cart", type: "POST", data: { "pid": 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"; } }); }); 12345678910111213141516171819202122

点击"加入购物车"按钮后页面跳转的实现:product.html导入的product.js文件里面实现了点击后跳转

相关知识

【SpringBoot项目
基于Springboot实现的花店平台
【2024最新】springboot网上商城购物系统lw+ppt
鲜花预约配送系统:从需求分析到功能实现
Java实现鲜花销售系统
基于springboot网上花店平台系统
基于微信小程序的花店鲜花商城系统(源码+论文)
Springboot计算机毕业设计网上鲜花销售系统6r845
如何设计一个网上商城系统,使其在用户注册、购物、订单管理等方面提供高效便捷的服务?
基于SpringBoot的花店管理系统

网址: 10天手敲一个SpringBoot网上商城项目(七)——显示商品详情功能及加入购物车功能的实现 https://m.huajiangbk.com/newsview820939.html

所属分类:花卉
上一篇: 基于springboot网上购物
下一篇: 怎么开线上超市