加入购物车
1.数据创建
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;
t_cart.sql
2 创建实体类
public class Cart extends BaseEntity{ private Integer cid; private Integer uid; private Integer pid; private Long price; private Integer num; //... }
Cart
3 持久层
3.1 规划查询的SQL语句
1.先购物车表中插入数据。
insert into t_cart (cid除外) values (值列表)
2.当前的商品已经在购物车中存在,则直接更新num的数量即可
update t_cart set num=? where cid=?
3.在插入或者更新具体执行哪个语句,取决于数据库中是否有当前的这个购物车商品的数据,得查询才能确定。
select * from t_cart where cid=? and uid=?
3.2设计接口与抽象方法
创建一个CartMapper即可持久层的文件
package com.cy.store.mapper; import com.cy.store.entity.Cart; import org.apache.ibatis.annotations.Param; import java.util.Date; /** 处理购物车数据的持久层接口 */ 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 购物车中的数据 */ Cart findByUidAndPid( @Param("uid") Integer uid, @Param("pid") Integer pid); }
3.3 配置SQL映射
创建一个CartMapper.xml映射文件,并添加以上三个方法的SQL语句映射。
<?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> <!-- 插入购物车数据:Integer insert(Cart cart) --> <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>
CartMapper–insert
测试
**CartMapperTests **
package com.cy.store.mapper; import com.cy.store.entity.Cart; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import java.util.Date; @SpringBootTest public class CartMapperTests { @Autowired private CartMapper cartMapper; @Test public void insert() { Cart cart = new Cart(); cart.setUid(8); cart.setPid(10000011); cart.setNum(2); cart.setPrice(1000L); Integer rows = cartMapper.insert(cart); System.out.println("rows=" + rows); } @Test public void updateNumByCid() { Integer rows = cartMapper.updateNumByCid(1,4,"李四",new Date()); System.out.println("rows=" + rows); } @Test public void findByUidAndPid() { Cart cart = cartMapper.findByUidAndPid(8,10000011); System.out.println(cart); } }
CartMapperTests–insert
4 业务层
4.1 规划异常
1.插入数据时可能产生异常:InsertException
2.更新数据时可能产生异常:UpdateException
4.2 设计接口与抽象方法
创建一个ICartService接口文件。
package com.cy.store.service; public interface ICartService { /** * 将商品添加到购物车 * @param uid 用户id * @param pid 商品id * @param amount 新增数量 * @param username 用户名(修改者) */ void addToCart(Integer uid, Integer pid, Integer amount, String username); }
4.3 实现抽象方法
创建一个CartServiceImpl的实现类。
package com.cy.store.service.impl; import com.cy.store.entity.Cart; import com.cy.store.entity.Product; import com.cy.store.mapper.CartMapper; import com.cy.store.mapper.ProductMapper; import com.cy.store.service.ICartService; import com.cy.store.service.ex.InsertException; import com.cy.store.service.ex.UpdateException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.Date; @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) { // 查询当前要添加的购物车是否在表中已存在 Cart result = cartMapper.findByUidAndPid(uid, pid); Date date = new Date(); if (result==null){//表示这个商品从来没有被添加到购物车中,则进行新增操作 //需要创建一个cart对象 Cart cart=new Cart(); //补全数据:参数传递的数据 cart.setUid(uid); cart.setPid(pid); cart.setNum(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{//表示当前商品在购物车中已经存在,则更新这条数据的num值 Integer num = result.getNum() + amount; Integer rows = cartMapper.updateNumByCid(result.getCid(), num, username, date); if (rows!=1){ throw new UpdateException("更新数据时产生未知的异常"); } } } }
CartServiceImpl–addToCart
测试
再创建一个对应的测试类CartServiceTests类
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; import java.util.List; //@SpringBootTest:表示标注当前的类是测试类,不会随同项目一块打包 @SpringBootTest //@RunWith:表示启动这个单元测试类(单元测试类是不能够运行的),需要传递一个参数,必须是SpringRunner的实例类型 //@RunWith(SpringRunner.class) public class CartServiceTests { @Autowired private ICartService cartService; @Test public void addToCart(){ // cartService.addToCart(8,10000012,1,"test"); cartService.addToCart(8,10000011,1,"test"); } }
CartServiceTests–addToCart
5 控制器
5.1 处理异常
1.没有需要处理异常
5.2 设计请求
2.设计请求处理路径
/carts/add_to_cart GET pid,amount,session JsonResult<Void>
5.3 处理请求
3.完成请求处理方法的编写。
package com.cy.store.controller; import com.cy.store.service.ICartService; import com.cy.store.util.JsonResult; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpSession; @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<>(OK); } }
CartController–addToCart
测试
先登录在测试
http://localhost:8080/carts/add_to_cart?pid=10000021&amount=5
6 前端页面
在product.html页面给[加入购物车]按钮添加点击事件,并发送ajax请求。
// <!-- add_to_cart --> $("#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("加入购物车失败!"); } }, error: function(xhr) { alert("加入购物车产生未知异常" + xhr.message); } }); }); // <!-- add_to_cart -->
在ajax函数中data参数的数据设置的方式:
data:$(“from表单选择”).serialize()。当参数过多并且在同一个表单中,字符串的提交等
data:new FormData($(“form表单选择”)[0])。只适用提交文件
data:“username=Tom”。适合参数值固定并且参数值列表邮箱。可以进行手动拼接
let user="Tom" data: "username"+user
- 适用JSON格式提交数据:
data:{ "username": "Tom" "age": 18, "sex": 0 }
product.html–add_to_cart
测试
略
README–加入购物车