62. 购物车-加入购物车-控制器层
(a) 统一处理异常
无
(b) 设计请求
设计“购物车-加入购物车”的请求方式:
请求路径:/carts/add_to_cart
请求参数:Integer pid, Integer num, HttpSession session
请求方式:POST
响应数据:JsonResult<Void>
© 处理请求
创建cn.tedu.store.controller.CartController
控制器类,继承自BaseController
,在类之前添加@RestController
和@RequestMapping("carts")
注解,在类中声明@Autowired private ICartService cartService;
业务层对象。
在控制器类中添加处理请求的方法:
@RequestMapping("add_to_cart")
public JsonResult<Void> addToCart(Integer pid, Integer num, HttpSession session) {
// 从session中获取uid和username
// 调用业务层对象的方法执行任务
// 响应成功
}
打开浏览器,登录,然后通过http://localhost:8080/carts/add_to_cart?pid=10000017&num=10
测试。
63. 购物车-加入购物车-前端界面
64. 购物车-显示列表-持久层
(a) 规划SQL语句
select
cid, uid, pid, t_cart.num, t_cart.price, title, image, t_product.price
from
t_cart
left join
t_product
on
t_cart.pid=t_product.id
where
uid=?
order by
t_cart.created_time DESC
(b) 接口与抽象方法
创建cn.tedu.store.vo.CartVO
类:
public class CartVO implements Serializable {
private Integer cid;
private Integer uid;
private Integer pid;
private Integer num;
private Long price;
private Long realPrice;
private String title;
private String image;
// SET/GET/hashCode/equals/toString
}
在持久层接口中添加抽象方法:
List<CartVO> findByUid(Integer uid);
© 配置映射
映射:
<!-- 根据用户id查询该用户的购物车列表 -->
<!-- List<CartVO> findByUid(Integer uid) -->
<select id="findByUid"
resultType="cn.tedu.store.vo.CartVO">
SELECT
cid, uid,
pid, t_cart.num,
t_cart.price, t_product.price AS realPrice,
title, image
FROM
t_cart
LEFT JOIN
t_product
ON
t_cart.pid=t_product.id
WHERE
uid=#{uid}
ORDER BY
t_cart.created_time DESC
</select>
测试:
@Test
public void findByUid() {
Integer uid = 7;
List<CartVO> list = mapper.findByUid(uid);
System.err.println("count=" + list.size());
for (CartVO item : list) {
System.err.println(item);
}
}
65. 购物车-显示列表-业务层
(a) 规划异常
无
(b) 接口与抽象方法
List<CartVO> getByUid(Integer uid);
© 实现抽象方法
私有化实现持久层中定义的方法:
/**
* 根据用户id查询该用户的购物车列表
* @param uid 用户id
* @return 该用户的购物车列表,如果该用户购物车为空,则返回空集合
*/
private List<CartVO> findByUid(Integer uid) {
return cartMapper.findByUid(uid);
}
重写接口中的方法:
@Override
public List<CartVO> getByUid(Integer uid) {
return findByUid(uid);
}
测试:
@Test
public void getByUid() {
Integer uid = 7;
List<CartVO> list = service.getByUid(uid);
System.err.println("count=" + list.size());
for (CartVO item : list) {
System.err.println(item);
}
}
66. 购物车-显示列表-控制器层
(a) 统一处理异常
无
(b) 设计请求
设计“购物车-显示列表”的请求方式:
请求路径:/carts/
请求参数:HttpSession session
请求方式:GET
响应数据:JsonResult<List<CartVO>>
© 处理请求
@RequestMapping("/")
public JsonResult<List<CartVO>> getByUid(HttpSession session) {
// 从session中获取uid
Integer uid = getUidFromSession(session);
// 调用业务层对象的方法执行任务
List<CartVO> data = cartService.getByUid(uid);
// 响应成功
return new JsonResult<>(SUCCESS, data);
}
67. 购物车-显示列表-前端界面
68. 购物车-增加商品数量-持久层
(a) 规划SQL语句
可以直接使用此前的:
update t_cart set num=? where cid=?
在执行增加数量之前,还是应该检查数据是否存在,及数据归属是否正确:
select * from t_cart where cid=?
(b) 接口与抽象方法
Cart findByCid(Integer cid);
© 配置映射
映射:
<!-- 根据购物车数据id查询购物车数据详情 -->
<!-- Cart findByCid(Integer cid) -->
<select id="findByCid"
resultMap="CartEntityMap">
SELECT
*
FROM
t_cart
WHERE
cid=#{cid}
</select>
测试:
@Test
public void findByCid() {
Integer cid = 5;
Cart cart = mapper.findByCid(cid);
System.err.println(cart);
}
69. 购物车-增加商品数量-业务层
(a) 规划异常
先检查数据是否存在:CartNotFoundException
再检查数据归属是否正确:AccessDeniedException
最后还需要执行更新操作:UpdateException
(b) 接口与抽象方法
void addNum(Integer cid, Integer uid, String username) throws CartNotFoundException, AccessDeniedException, UpdateException;
© 实现抽象方法
私有化实现:
/**
* 根据购物车数据id查询购物车数据详情
* @param cid 购物车数据id
* @return 匹配的购物车数据详情,如果没有匹配的数据,则返回null
*/
private Cart findByCid(Integer cid) {
return cartMapper.findByCid(cid);
}
规划所写的方法:
public void addNum(Integer cid, Integer uid, String username) throws CartNotFoundException, AccessDeniedException, UpdateException {
// 根据参数cid查询数据
// 判断查询结果是否为null:CartNotFoundException
// 判断查询结果中的uid与参数uid是否不同:AccessDeniedException
// 从查询结果中获取尝试购买的原数量
// 将数量更新为原数量+1的结果
}
实现代码:
@Override
public void addNum(Integer cid, Integer uid, String username)
throws CartNotFoundException, AccessDeniedException, UpdateException {
// 根据参数cid查询数据
Cart result = findByCid(cid);
// 判断查询结果是否为null:CartNotFoundException
if (result == null) {
throw new CartNotFoundException(
"增加失败!尝试访问的购物车数据不存在!");
}
// 判断查询结果中的uid与参数uid是否不同:AccessDeniedException
if (result.getUid() != uid) {
throw new AccessDeniedException(
"增加失败!不允许操作他人的数据!");
}
// 从查询结果中获取尝试购买的原数量
Integer oldNum = result.getNum();
// 将数量更新为原数量+1的结果
updateNum(cid, oldNum + 1, username, new Date());
}
测试:
@Test
public void addNum() {
try {
Integer cid = 6;
Integer uid = 7;
String username = "土豪";
service.addNum(cid, uid, username);
System.err.println("OK.");
} catch (ServiceException e) {
System.err.println(e.getClass().getName());
System.err.println(e.getMessage());
}
}
70. 购物车-增加商品数量-控制器层
(a) 统一处理异常
需要处理:CartNotFoundException
(b) 设计请求
设计“购物车-增加商品数量”的请求方式:
请求路径:/carts/{cid}/add_num
请求参数:@PathVariable("cid") Integer cid, HttpSession session
请求方式:POST
响应数据:JsonResult<Void>
© 处理请求
@RequestMapping("{cid}/add_num")
public JsonResult<Void> addNum(
@PathVariable("cid") Integer cid,
HttpSession session) {
// 从session中获取uid和username
Integer uid = getUidFromSession(session);
String username = getUsernameFromSession(session);
// 调用业务层对象的方法执行任务
cartService.addNum(cid, uid, username);
// 响应成功
return new JsonResult<>(SUCCESS);
}
http://127.0.0.1:8080/carts/6/add_num
71. 购物车-增加商品数量-前端界面
作业
-
在购物车列表中删除购物车数据
-
在购物车列表中点击减号以减少商品的数量