Project(15)——购物车 - 向购物车加入数据

Project(15)——购物车 - 向购物车加入数据

64、购物车 - 加入购物车 - 创建数据表


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

65、购物车 - 加入购物车 - 创建实体类

创建cn.tedu.store.entity.Cart实体类,继承自BaseEntity

66、购物车 - 加入购物车 - 持久层

将商品添加到购物车,执行的sql语句大致是:


INSERT INTO t_cart(
    uid, gid, num, created_user,
    created_time, modified_user, modified_time
) VALUES(
    #{uid}, #{gid}, #{num}, #{createdUser},
    #{createdTime}, #{modifiedUser}, #{modifiedTime}
)

需要注意的是,并不是每次点击“添加购物车”都会产生新数据,例如:7 号用户已经添加了 1 号商品,数量为 2:


uid  gid  num
7    1    2

此时,如果用户再次点击 1 号商品的“加入购物车”,添加一个到购物车中,这时,应该只修改原有的数量数据,而不添加新的数据:


uid  gid  num
7    1    3

所以,加入购物车功能还可能执行的sql语句:


UPDATE
    t_cart
SET
    num=?, modified_user=?, modified_time=?
WHERE
    cid=?


用户每次点击“加入购物车”时,到底执行INSERT操作还是UPDATE操作,取决于该用户的购物车中有没有该商品。实现该判断的sql查询语句大致是:


SELECT
    *
FROM
    t_cart
WHERE
    uid=? AND gid=?


执行以上查询时,如果查询到有效结果,则表示“该用户的购物车中已有该商品”,反之,则表示“该用户的购物车中没有该商品”。如果查询到有效结果,后续将执行UPDATE操作,即:更新购物车中商品的数量,则需要将原数量读出来,用于结合用户此次提交的增量,计算新的数量,并且,还要读出这条数据的 id,便于执行UPDATE操作,则以上查询应该调整为:


SELECT
    cid, num
FROM
    t_cart
WHERE
    uid=? AND gid=?


分析完成,创建cn.tedu.store.mapper.CartMapper持久层接口,并添加以上 3 个功能对应的抽象方法:


/**
 * 处理购物车数据的持久层接口
 * @author DELL
 *
 */
public interface CartMapper {
	
	/**
	 * 插入一条新的购物车数据
	 * @param cart
	 * @return
	 */
	Integer insert(Cart cart);
	
	/**
	 * 更新商品数据
	 * @param cid 购物车数据 cid
	 * @param num 商品数量
	 * @param modifiedUser 修改人
	 * @param modifiedTime 修改时间
	 * @return
	 */
	Integer updateNum(
			@Param("cid") Integer cid,
			@Param("num") Integer num,
			@Param("modifiedUser") String modifiedUser,
			@Param("modifiedTime") Date modifiedTime);
	
	/**
	 * 根据 uid 和 gid 查询购物车数据
	 * @param uid 用户 uid
	 * @param gid 商品 gid
	 * @return 商品数据
	 */
	Cart findByUidAndGid(
			@Param("uid") Integer uid,
			@Param("gid") Long gid);
	
	
}


复制得到CartMapper.xml配置文件,修改namespace属性的值,并配置以上 3 个抽象方法的映射:


<?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:xml文件对应哪个接口 -->
<mapper namespace="cn.tedu.store.mapper.CartMapper">
    
    <!-- 插入一条新的购物车数据 -->
    <!-- Integer insert(Cart cart) -->
    <insert id="insert" useGeneratedKeys="true" keyProperty="cid">
    INSERT INTO t_cart(
        uid, gid, num, created_user,
        created_time, modified_user, modified_time
    ) VALUES (
        #{uid}, #{gid}, #{num}, #{createdUser},
        #{createdTime}, #{modifiedUser}, #{modifiedTime}
    )
    </insert>
    
    
    
    
    <!-- 更新商品数据 -->
    <!-- Integer updateNum(
			@Param("cid") Integer cid,
			@Param("num") Integer num,
			@Param("modifiedUser") String modifiedUser,
			@Param("modifiedTime") Date modifiedTime) -->
    <update id="updateNum">
    UPDATE
        t_cart
    SET
        num=#{num}, modified_user=#{modifiedUser}, modified_time=#{modifiedTime}
    WHERE
        cid=#{cid}
    </update>
    
    
    
    
    
    
    <!-- 根据 uid 和 gid 查询购物车数据 -->
    <!-- Cart findByUidAndGid(
			@Param("uid") Integer uid,
			@Param("gid") Long gid) -->
    <select id="findByUidAndGid" resultType="cn.tedu.store.entity.Cart">
    SELECT
        cid, num
    FROM
        t_cart
    WHERE
        uid=#{uid} AND gid=#{gid}
    </select>
    
    
</mapper>


src/test/java下创建cn.tedu.store.mapper.CartMapperTests测试类,编写并执行单元测试:


/**
 * 购物车数据持久层测试类
 * @author DELL
 *
 */

@SpringBootTest
public class CartMapperTests {
	
	@Autowired
	private CartMapper cartMapper;
	
	/**
	 * 测试查询热销列表
	 */
	@Test
	public void testInsert() {
		Cart cart = new Cart();
		cart.setGid(10000042L);
		cart.setNum(1);
		cart.setUid(7);
		cart.setCreatedUser("酒厂管理员");
		Date now = new Date();
		cart.setCreatedTime(now);
		cart.setModifiedUser("酒厂管理员");
		cart.setModifiedTime(now);
		cartMapper.insert(cart);
		
		System.err.println("End!");
	}
	
	/**
	 * 测试根据 uid 和 gid 查询购物车数据
	 */
	@Test
	public void testFindByUidAndGid() {
		Integer uid = 7;
		Long gid = 10000017L;
		Cart cart = cartMapper.findByUidAndGid(uid, gid);
		System.err.println(cart);
	}
	
	/**
	 * 测试更新商品数据
	 */
	@Test
	public void testUpdateNum() {
		Integer cid = 1;
		Integer num = 3;
		String modifiedUser = "Gin";
		Date now = new Date();
		Date modifiedTime = now;
		cartMapper.updateNum(cid, num, modifiedUser, modifiedTime);
		System.err.println("End!");
	}
	
	
}


67、购物车 - 加入购物车 - 业务层

此次业务层将调用持久层开发的三个方法,其中,查询的方法不会抛异常,因为无论是否查询到数据,此操作都是正确的;而插入数据和更新数据有可能抛出InsertExceptionUpdateException异常。

创建cn.tedu.store.service.ICartService业务层接口,并添加抽象方法:


/**
 *  处理购物车数据的业务层接口
 * @author DELL
 *
 */
public interface ICartService {
	
	/**
	 * 向购物车中添加数据
	 * @param cart
	 */
	void addToCart(Cart cart, Integer uid, String username) throws InsertException, UpdateException;
	
}

创建cn.tedu.store.service.impl.CartServiceImpl业务层实现类,实现以上接口,添加@Service注解,在类中声明@Autowired private CartMapper cartMapper持久层对象:

私有化实现持久层中的 3 个抽象方法:

重写接口中的抽象方法:


/**
 * 处理购物车数据的业务层实现类
 * @author DELL
 *
 */
@Service
public class CartServiceImpl implements ICartService {
	
	@Autowired
	private CartMapper cartMapper;
	
	/**
	 * 向购物车中添加商品数据
	 */
	@Override
	public void addToCart(Cart cart, Integer uid, String username) {
		// 根据 cart 获取的 gid 和参数 uid 进行数据查询
		// 判断查询结果是否为 null
		Long gid = cart.getGid();
		Cart result = findByUidAndGid(uid, gid);
		// 是:
		// -- 直接插入数据
		// -- 基于参数 uid 向参数 cart 中封装 uid
		// -- 基于参数 username 向参数 cart 中封装 createdUser、modifiedUser
		// -- 向参数 cart 中封装 createdTime、modifiedTime
		// -- 执行插入数据
		if(result == null) {
			cart.setUid(uid);
			cart.setCreatedUser(username);
			cart.setModifiedUser(username);
			Date now = new Date();
			cart.setCreatedTime(now);
			cart.setModifiedTime(now);
			Integer rows = insert(cart);
			if(rows != 1) {
				throw new InsertException("向购物车添加数据失败!出现未知错误,请联系系统管理员!");
			}
		}else {
			// 否:
			// -- 执行修改数量
			// -- 从查询结果中获取 cid
			// -- 从查询结果中获取商品原数量 num
			// -- 将以上获取的原数量 num 与参数 cart 中的数量相加,得到新数量
			// -- 执行修改数量
			Integer cid = result.getCid();
			Integer num = result.getNum();
			num = num + cart.getNum();
			Date now = new Date();
			Integer rows = updateNum(cid, num, username, now);
			if(rows != 1) {
				throw new UpdateException("向购物车添加数据失败!出现未知错误,请联系系统管理员!");
			}
		}
		
	}
	
	
	
	
	// 私有化实现持久层中的 3 个抽象方法
	/**
	 * 插入一条新的购物车数据
	 * @param cart
	 * @return
	 */
	private Integer insert(Cart cart) {
		return cartMapper.insert(cart);
	}
	
	/**
	 * 更新商品数据
	 * @param cid 购物车数据 cid
	 * @param num 商品数量
	 * @param modifiedUser 修改人
	 * @param modifiedTime 修改时间
	 * @return
	 */
	private Integer updateNum(
			@Param("cid") Integer cid,
			@Param("num") Integer num,
			@Param("modifiedUser") String modifiedUser,
			@Param("modifiedTime") Date modifiedTime) {
		return cartMapper.updateNum(cid, num, modifiedUser, modifiedTime);
	}
	
	/**
	 * 根据 uid 和 gid 查询购物车数据
	 * @param uid 用户 uid
	 * @param gid 商品 gid
	 * @return 商品数据
	 */
	private Cart findByUidAndGid(
			@Param("uid") Integer uid,
			@Param("gid") Long gid) {
		return cartMapper.findByUidAndGid(uid, gid);
	}
	
	
}


src/test/java中创建cn.tedu.store.service.CartServiceTests,编写并执行单元测试:


/**
 * 购物车数据业务层测试类
 * @author DELL
 *
 */

@SpringBootTest
public class CartServiceTests {
	
	@Autowired
	private ICartService service;
	
	/**
	 * 向购物车中添加数据
	 */
	@Test
	public void testAddToCart() {
		try {
			Cart cart = new Cart();
			Integer uid = 7;
			cart.setGid(10000011L);
			cart.setNum(2);
			String username = "Vodka";
			service.addToCart(cart, uid, username);
			System.err.println("End!");
		}catch(ServiceException e) {
			System.err.println(e.getClass().getName());
			System.out.println(e.getMessage());
		}
	}
	
	
}


68、购物车 - 加入购物车 - 控制器层

此次业务层并没有抛出新的异常,则无需处理异常。

新建cn.tedu.store.controller.CartController控制器类,继承自BaseController,添加@RestController@RequestMapping(“carts”)注解,并在类中声明@Autowired private CartMapper cartMapper业务层对象:


请求路径:/carts/add_to_cart
请求参数:Cart cart, HttpSession session
请求类型:post
响应数据:JsonResult<Void>

然后,在控制器类中添加处理请求的方法:


/**
 * 购物车信息的控制器类
 * @author DELL
 *
 */
@RestController
@RequestMapping("carts")
public class CartController extends BaseController {
	
	@Autowired
	private ICartService service;
	
	/**
	 * 像购物车中添加数据
	 * @param cart 购物车商品数据
	 * @param session 用于获取 uid、usernam
	 * @return
	 */
	@RequestMapping("add_to_cart")
	public JsonResult<Void> addToCart(Cart cart, HttpSession session){
		// 根据 session 获取 uid、username
		Integer uid = getUidFromSession(session);
		String username = getUsernameFromSession(session);
		
		// 执行向购物车插入数据操作
		service.addToCart(cart, uid, username);
		
		// 返回响应结果
		return new JsonResult<Void>(SUCCESS);
		
	}
	
}

完成后,先登录,在地址栏输入http://localhost:8080/carts/add_to_cart?gid=10000011&num=2进行测试。

69、购物车 - 加入购物车 - 前端页面

删除 product.js 文件中的以下代码:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值