使用SpringBoot+MyBatis+MySQL完成加入购物车

创建数据表

在数据中执行:

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;

创建实体类

在entity下创建Cart.java实体类文件。

public class Cart extends BaseEntity{
    private Integer cid;
    private Integer uid;
    private Integer pid;
    private Long price;
    private Integer num;
    // get、set、hashCode()、equals()和toString()方法
}

加入购物车-持久层

规划需要执行的SQL语句

① 向购物车表中插入数据;

insert into t_cart (cid除外) values(值列表)

② 当前的商品已经在购物车中存在,则直接更新num的数量;

update t_cart set num=?, created_user=?, created_time=? where cid=?

③ 在插入或者更新具体执行哪个语句,取决于数据库中是否有当前的这个购物车商品的数据,根据查询结果确定。

select * from t_cart where pid=? and uid=?

设计接口和抽象方法

创建一个CartMapper的接口文件。

package com.cy.store.mapper;

import com.cy.store.entity.Cart;

public interface CartMapper {
    /**
     * 插入购物车数据
     * @param cart 购物车数据
     * @return 受影响的行数
     */
    Integer insert(Cart cart);

    /**
     * 更新购物车某件商品的数量
     * @param cid 购物车数据id
     * @param num 更新的商品数量
     * @param modifiedUser 修改者时间
     * @return 受影响的行数
     */
    Integer updateNumByCid(Integer cid,
                           Integer num,
                           String modifiedUser,
                           String modififedTime);

    /**
     * 根据用户id和商品id查询购物车中的数据
     * @param uid 用户id
     * @param pid 商品id
     * @return 商品信息
     */
    Cart findByUidAndPid(Integer uid, Integer pid);
}

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">
<!-- namespace属性:用于指定当前的映射文件和哪个接口进行映射,需要指定接口的文件路径,需要标注包的完整路径 -->
<mapper namespace="com.cy.store.mapper.CartMapper">
    <resultMap id="CartEntityMap" type="com.cy.store.entity.Cart">
        <id column="id" property="id"/>
        <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>
    <select id="findByUidAndPid" resultMap="CartEntityMap">
         SELECT *
         FROM t_cart
         WHERE uid=#{uid} AND pid=#{pid}
    </select>
    <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},
            created_user=#{createdUser},
            created_time=#{createdTime}
        WHERE 
            cid=#{cid}
    </update>
</mapper>

单元测试

在单元测试方法中编写测试用例。

@RunWith(SpringRunner.class)
@SpringBootTest
public class CartMapperTests {
    @Autowired
    private CartMapper cartMapper;

    @Test
    public void insert() {
        Cart cart = new Cart();
        cart.setUid(14);
        cart.setPid(100000425);
        cart.setNum(2);
        cart.setPrice(1000L);
        cartMapper.insert(cart);
    }

    @Test
    public void updateNumByCid() {
        cartMapper.updateNumByCid(1, 5, "test002", new Date());
    }

    @Test
    public void findByUidAndPid() {
        System.out.println(cartMapper.findByUidAndPid(14,100000425));
    }
}

加入购物车-业务层

规划异常

  • 插入数据时可能产生的异常:InsertException;
  • 更新数据时可能产生的异常:UpdateException。

接口和抽象方法

创建一个ICartService接口文件,在这个接口文件中设计抽象方法。

public interface ICartService {
    /**
     * 将商品添加到购物车中
     * @param uid 用户id
     * @param pid 商品id
     * @param amount 新增数量
     * @param username 用户名(修改者)
     */
    void addToCart(Integer uid, Integer pid, Integer amount, String username);
}

实现接口

创建CartServiceImpl类,并实现ICartService接口,在类的定义前添加@Service注解。在类中声明CartMapper持久层对象和IProductService处理商品数据的业务对象,并都添加@Autowired注解修饰。

@Service
public class CartServiceImpl implements ICartService {
    /** 购物车的业务层依赖于购物车的持久层和商品的持久层 */
    @Autowired
    private CartMapper cartMapper;
    @Autowired
    private IProductService productService;

    @Override
    public void addToCart(Integer uid, Integer pid, Integer amount, String username) {
        // 查询当前要添加到购物车的商品是否在表中已存在
        Cart result = cartMapper.findByUidAndPid(uid, pid);
        Date now = new Date();
        if(result == null) { // 表示商品从来没有被添加到购物车中,则进行新增操作
            // 创建一个cart对象
            Cart cart = new Cart();
            // 补全数据:参数传递的数据
            cart.setUid(uid);
            cart.setPid(pid);
            cart.setNum(amount);
            // 补全价格,来自商品中的数据
            Product product = productService.findById(pid);
            cart.setPrice(product.getPrice());
            // 补全4个日志
            cart.setCreatedUser(username);
            cart.setCreatedTime(now);
            cart.setModifiedUser(username);
            cart.setModifiedTime(now);
            // 执行数据的插入操作
            Integer rows = cartMapper.insert(cart);
            if (rows != null) {
                throw new InsertException("插入数据时产生未知的异常");
            }
        } else { // 表示当前的商品在购物车中已经存在,则更新这条数据的num值
            Integer num = result.getNum() + amount;
            Integer rows = cartMapper.updateNumByCid(
                                        result.getCid(),
                                        num,
                                        username,
                                        now);
            if (rows != 1) {
                throw new UpdateException("更新数据时产生未知的异常");
            }
        }
    }
}

单元测试

在service包下创建测试类CartServiceTests,并编写测试方法。

@SpringBootTest
@RunWith(SpringRunner.class)
public class CartServiceTests {
    @Autowired
    private ICartService cartService;

    @Test
    public void addToCart() {
        cartService.addToCart(14, 100000425, 3, "test005");
    }
}

加入购物车-控制层

规划异常

无需要处理的异常。

设计请求

请求路径:/carts/add_to_cart
请求方法:GET
请求数据:Integer pid, Interger amount, Httpsession session
响应结果:JsonResult<Void>

编写请求处理方法

创建一个CartController类。

@RequestMapping("carts")
@RestController
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);
    }
}

启动项目后先登录再访问,在浏览器输入url地址进行测试。

加入购物车-前端页面

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

$("#btn-add-to-cart").click(function () {
				$.ajax({
					url: "/carts/add_to_cart",
					type: "GET",
					data: {
						"pid": id,
						"amount": $("#num").val()
					},
					dataType: "JSON",
					success: function (json) {
						if (json.state == 200) {
							alert("加入购物车成功");
						} else {
							alert("加入购物车失败");
						}
					},
					error: function (xhr) {
						alert("加入购物车时产生未知的异常" + xhr.message);
					}
				});
			});

在Ajax函数中添加数据的方式

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

$("form表单选择").serialize()。当参数过多并且在同一个表单中,字符串的提交等。

第二种方式:

new FormData($("form表单选择")[0]),只适用于提交文件

第三种方式: data: “username=Tom”,适合参数值固定并且参数值列表有限,可以进行手动拼接

let user = "Tom"
data: "username" + user

第四种方式:适用于JSON格式提交数据:

data: {
    "username": "Tom",
    "age": 19,
    "sex": 0
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值