做网站用框架么,培训课程总结,o2o商城系统,网站开发海报#x1f9f8;安清h#xff1a;个人主页 #x1f3a5;个人专栏#xff1a;【Spring篇】【计算机网络】【Mybatis篇】
#x1f6a6;作者简介#xff1a;一个有趣爱睡觉的intp#xff0c;期待和更多人分享自己所学知识的真诚大学生。 目录
#x1f680;1.加入购物车-数…
安清h个人主页 个人专栏【Spring篇】【计算机网络】【Mybatis篇】
作者简介一个有趣爱睡觉的intp期待和更多人分享自己所学知识的真诚大学生。 目录
1.加入购物车-数据创建
2.加入购物车-实体类
3.加入购物车-持久层
✨3.1规划需要执行的SQL语句
✨3.2设计接口和抽象方法
✨3.3 SQL映射
4.加入购物车-业务层
✨4.1规划异常
✨4.2接口和抽象方法的设计
✨4.3实现接口
5.加入购物车-控制层
✨5.2设计请求
✨5.3处理请求
6.加入购物车-前端页面
1.显示购物车列表- 持久层
✨1.1规划SQL语句
✨1.2构建VO类
✨1.3设计接口和抽象方法
✨1.4配置SQL映射
2.显示购物车列表- 业务层
3.显示购物车列表- 控制层
✨3.1设计请求
✨3.2处理请求
4.显示购物车列表- 前端页面
1. 增加购物车商品数量-持久层
✨1.1规划需要执行的SQL语句
✨1.2设计接口和抽象方法
✨1.3配置SQL映射 2.增加购物车商品数量-业务层
✨2.1规划异常
✨2.2设计接口和抽象方法
✨ 2.3实现方法 3.增加购物车商品数量-控制层
✨3.1处理异常
✨3.2设计请求
✨3.3处理请求 4.增加购物车商品数量-前端页面 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)
) ENGINEInnoDB DEFAULT CHARSETutf8;num当用户重复添加商品时只修改num就可以了无需再重复添加商品。
2.加入购物车-实体类
public class Cart extends BaseEntity{private Integer cid;private Integer uid;private Integer pid;private Long price;private Integer num;
。。。。。。
}
3.加入购物车-持久层
✨3.1规划需要执行的SQL语句
1.向购物车表中插入数据。
insert into t_cart values(值列表)
2.当当前的商品已经在购物车中存在则直接更新num的数量即可。
update t_cart set num? where cid? 3.在插入或更新具体执行那个语句取决于数据库中是否有当前的这个购物车商品的数据得去查询才能查询。对当前的用户的pid进行查询加上uid?而不是对当前的整张表进行查询。
select * from t_cart where pid? and uid?
✨3.2设计接口和抽象方法
创建一个CartMapper接口持久层的文件。
/*** 插入购物车数据* param cart 购物车数据* return 受影响的行数* 插入时最好放在一个对象中传递所以用Cart参数列表* 插入后在业务层可能调用需要有返回值判断能否插入成功*/Integer insert(Cart cart);/*** 更新购物车某件商品的数量* param cid 购物数据id* param num 更新的数量* param modifiedUser 修改人* param modifiedTime 修改时间* return 受影响的行数* 更新时涉及到修改人和修改时间除了cid外还需要知道数量num*/Integer updateNumByCid(Integer cid, Integer num, String modifiedUser, Date modifiedTime);/*** 根据用户的id和商品的id来查询购物车中的数据* param uid 用户id* param pid 商品id*/Cart findByUidAndPid(Integer uid,Integer pid);
✨3.3 SQL映射
1.创建一个CartMapper.xml映射文件添加以上三个抽象方法的SQL映射。
?xml version1.0 encodingUTF-8 ?
!DOCTYPE mapperPUBLIC -//mybatis.org//DTD Mapper 3.0//ENhttp://mybatis.org/dtd/mybatis-3-mapper.dtd
mapper namespacecom.cy.store.mapper.CartMapperresultMap idCartEntityMap typecom.cy.store.entity.Cartid propertycid columncid/result columncreated_user propertycreatedUser/resultresult columncreated_time propertycreatedTime/resultresult columnmodified_user propertymodifiedUser/resultresult columnmodified_time propertymodifiedTime/result/resultMapinsert idinsert useGeneratedKeystrue keyPropertycidinsert into t_cart (uid, pid, price, num, created_user, created_time, modified_user, modified_time)values (#{uid}, #{pid}, #{price}, #{num}, #{createdUser}, #{createdTime}, #{modifiedUser}, #{modifiedTime})/insertupdate idupdateNumByCidupdate t_cart set num#{num},modified_user#{modifiedUser},modified_time#{modifiedTime}where cid#{cid}/updateselect idfindByUidAndPid resultMapCartEntityMapselect * from t_cart where pid#{pid} and uid#{uid}/select
/mapper
2.进行测试
SpringBootTest
public class CartMapperTests {Autowiredprivate CartMapper cartMapper;Testpublic void insert(){Cart cart new Cart();cart.setNum(3);cart.setPid(10000002);cart.setUid(6);cartMapper.insert(cart);}Testpublic void updateNumByCid(){cartMapper.updateNumByCid(1,6,小明,new Date());}Testpublic void findByUidAndPid(){Cart cart cartMapper.findByUidAndPid(6,10000002);System.err.println(cart);}
}
4.加入购物车-业务层
✨4.1规划异常
1.插入数据时可能产生异常InsertException。
2.更新数据时可能产生异常UpdateException。
✨4.2接口和抽象方法的设计
分析
1.首先要进行商品的查询这里面通过findByUidAndPid方法必须要传递过来的是uid和pid的字段。
2.假设拿到后就要对原有的数据进行更新需要传递的字段有cid,num,username。 /*** 将商品添加到购物车中* param uid 用户id* param pid 商品id* param amount 新增数量* param username 用户名修改者*/void addToCart(Integer uid,Integer pid,Integer amount,String username);
✨4.3实现接口
1.创建一个CartServiceImpl的实现类。
Service
public class CartServiceImpl implements ICartService {
//购物车的业务层依赖于购物车的持久层和商品的持久层Autowiredprivate CartMapper cartMapper;Autowired//购物车中的一些定义的字段实际上是从商品表中分离出来的private ProductMapper productMapper;Overridepublic 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.setPid(pid);cart.setUid(uid);//这里的amount暂且理解为在前端加好把总数传递过来cart.setNum(amount);//补全价格来自于商品中的数据Product product productMapper.findById(pid);cart.setPrice(product.getPrice());//补全四日志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 cid result.getCid();Integer rows cartMapper.updateNumByCid(cid,num,username,date);if(rows ! 1){throw new UpdateException(更新时产生未知的异常);}}}
}
2. 再创建对应的测试类CartServiceTests。
SpringBootTest
public class CartServiceTests {Autowiredprivate ICartService cartService;Testpublic void addToCart(){cartService.addToCart(6,10000013,2,北伐不成功不改名);}
}
5.加入购物车-控制层
1.没有需要处理的异常。
✨5.2设计请求 请求路径/carts/add_to_cart 请求方式POST 请求数据Integer pidInteger amountHttpSession session 响应结果JsonResultVoid ✨5.3处理请求
1.创建一个CartController类具体代码如下
RequestMapping(carts)
RestController
public class CartController extends BaseController{Autowiredprivate ICartService cartService;RequestMapping(add_to_cart)public JsonResultVoid addToCart(Integer pid, Integer amount, HttpSession session){cartService.addToCart(getuidFromSession(session),pid,amount,getUsernameFromSession(session));return new JsonResult(OK);}
} 2.登录后访问http://localhost:8080/carts/add_to_cart?pid10000003amount1
6.加入购物车-前端页面
在product.html页面给【加入购物车】按钮添加点击事件并发送ajax请求。
$(#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.state200){alert(加入购物车成功);}else{alert(加入购物车失败);}},error:function (xhr){alert(加入购物车时产生未知的异常xhr.message);}});});
在ajax函数中data参数的数据设置的方式
data:$(form表单选择).serialize()。适合要么就是可以全部选择的或者手动输入的串的类型。当参数过多并且在同一个字符串中。data:new FormData($(form表单选择)[0])。只适用提交文件其他形式提交不了。data:usernameTom。适合参数值固定并且参数值列表有限可以进行手动拼接。 let user tom;
data:usernameuser 适用JSON格式提交数据 data:{username:tom,age:18,sex:0
}
1.显示购物车列表- 持久层
✨1.1规划SQL语句 分析上图可知红线框住的图片和商品标题来自于product表而蓝线框住的应该属于 cart表单价和数量应该是从购物车中传过来的再根据两者计算总金额。由于数据来自于两张表中的部分字段所以要用到关联查询。
#多表查询如果字段不重复则不需要显式声明字段属于哪张表
select cid,uid,pid,t_cart.price,t_cart.num,t_product.image,t_product.title,t_product.price as real
from t_cart left join t_product on t_cart.pidt_product.id
where uid#{uid}
order by t_cart.createdTime DESC;
✨1.2构建VO类 VOValue Object值对象。当进行select查询时查询的结果属于多张表中的内容此时发现结果集不能直接使用某个POJO实体类来接收POJO实体类不能包含多表查询出来的结果。解决方案重新构建一个新的对象这个对象用于存储所查询出来的结果集对应的映射所以把这样的对象称之为值对象。 在com.cy.store下新建一个包VO在VO包里创建CartVO类。
//购物车数据的VO类(Value Object)值对象
public class CartVO implements Serializable {private Integer cid;private Integer uid;private Integer pid;private Long price;private Integer num;private String title;private String image;private Long realPrice;
......
}
✨1.3设计接口和抽象方法
在CartMapper中编写如下代码
ListCartVO findVOByUid(Integer uid);
✨1.4配置SQL映射 select idfindVOByUid resultTypecom.cy.store.Vo.CartVOselect cid,uid,pid,t_cart.price,t_cart.num,t_product.image,t_product.title,t_product.price as realPricefrom t_cart left join t_product on t_cart.pidt_product.idwhere uid#{uid}order by t_cart.createdTime DESC/select
单元测试 Testpublic void findVOByUid(){System.out.println(cartMapper.findVOByUid(6));}
2.显示购物车列表- 业务层
1.先编写业务层的接口方法。
ListCartVO getVOByUid(Integer uid);
2.在实现类中实现方法。
Overridepublic ListCartVO getVOByUid(Integer uid) {ListCartVO list cartMapper.findVOByUid(uid);return list;}
3.显示购物车列表- 控制层
✨3.1设计请求 请求路径/carts/只要发一个carts就可以把列表返回不需要carts下的什么 请求方式GET 请求数据HttpSession session 响应结果JsonResultListCartVO ✨3.2处理请求
1.实现请求处理方法的代码编写。 RequestMapping({/,})public JsonResultListCartVO getVOByUid(HttpSession session){ListCartVO data cartService.getVOByUid(getuidFromSession(session));return new JsonResult(OK,data);}
2.先登录再进行功能测试访问http://localhost:8080/carts。
4.显示购物车列表- 前端页面
要把cart.html页面通过向Controller层中的getVOByUid方法发送请求就可以返回所有的数据。
1.先注释掉以下代码
script src../js/cart.js typetext/javascript charsetutf-8/script
2.用户一打开页面就自动发送请求请求数据。读取form表单对它的结构做一个了解因为要把数据显示在form表单中。 actionorderConfirm.htmltbody标签的idcart-list属性自动加载的内容需要体现在tbody中。typebutton结算按钮的submit改成button后续需要传数据。 3.ready()函数来完成自动的ajax请求的提交和处理。
script typetext/javascript$(document).ready(function () {showCartList();});//展示购物车列表数据function showCartList() {$(#cart-list).empty();$.ajax({url: /carts,type: GET,dataType: JSON,success: function(json) {let list json.data;for (var i 0; i list.length; i) {//用户所拿到的是一个list集合在这个list集合中封装的是cartVO对象在这里先拿到这个list集合let tr tr\n td\n //在这里给复选框一个cid值在往后点击结算的时候会把这个cid值传递给下个页面//把这个数据提交给另一个页面是以参数的形式提交所以这个表单一定要有内部属性input namecids value#{cid} typecheckbox classckitem /\n /td\n tdimg src..#{image}collect.png classimg-responsive //td\n td#{title}#{msg}/td\n td¥span idgoodsPrice#{cid}#{singlePrice}/span/td\n td\n input typebutton value- classnum-btn οnclickreduceNum(1) /\n input idgoodsCount#{cid} typetext size2 readonlyreadonly classnum-text value#{num}\n input classnum-btn typebutton value οnclickaddNum(#{cid}) /\n /td\n tdspan idgoodsCast#{cid}#{totalPrice}/span/td\n td\n input typebutton οnclickdelCartItem(this) classcart-del btn btn-default btn-xs value删除 /\n /td\n /tr;tr tr.replaceAll(/#{cid}/g, list[i].cid);tr tr.replaceAll(/#{image}/g, list[i].image);tr tr.replaceAll(/#{title}/g, list[i].title);tr tr.replaceAll(/#{singlePrice}/g, list[i].realPrice);tr tr.replaceAll(/#{num}/g, list[i].num);tr tr.replaceAll(/#{totalPrice}/g, list[i].realPrice * list[i].num);if (list[i].realPrice list[i].price) {tr tr.replace(/#{msg}/g, 比加入时降价 (list[i].price - list[i].realPrice) 元);} else {tr tr.replace(/#{msg}/g, );}$(#cart-list).append(tr);}},error: function (xhr) {alert(加载购物车列表数据时产生未知的异常xhr.status);}});}/script
1. 增加购物车商品数量-持久层
✨1.1规划需要执行的SQL语句
1.执行更新t_cart表记录的num的值无需重复开发。
update t_cart set num#{num},modified_time{modifiedTime},modified_user#{modifiedUser} where cid#{cid}
2.根据cid查询购物车的这条记录是否存在。
select * from t_cart where cid?
✨1.2设计接口和抽象方法
Cart findByCid(Integer cid);
✨1.3配置SQL映射 select idfindByCid resultMapCartEntityMapselect * from t_cart where cid#{cid}/select
编写单元测试。 Testpublic void findByCid(){System.out.println(cartMapper.findByCid(2));} 2.增加购物车商品数量-业务层
✨2.1规划异常
1.在更新时会产生更新异常。
2.查询到的数据是否有访问权限。
3.查询的数据不存在抛出CartNotFoundException异常。
public class CartNotFoundException extends ServiceException{public CartNotFoundException() {super();}public CartNotFoundException(String message) {super(message);}public CartNotFoundException(String message, Throwable cause) {super(message, cause);}public CartNotFoundException(Throwable cause) {super(cause);}protected CartNotFoundException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {super(message, cause, enableSuppression, writableStackTrace);}
}
✨2.2设计接口和抽象方法 /*** 更新用户的购物车数据* param cid * param uid* param username * return 增加成功后新的数量*/Integer addNum(Integer cid,Integer uid,String username);
✨ 2.3实现方法 Overridepublic Integer addNum(Integer cid, Integer uid, String username) {Cart result cartMapper.findByCid(cid);if(result null){throw new CartNotFoundException(数据不存在);}if(!result.getUid().equals(uid)){throw new AccessDeniedException(数据非法访问);}Integer num result.getNum()1;Integer rows cartMapper.updateNumByCid(cid,num,username,new Date());if(rows ! 1){throw new UpdateException(更新时产生异常);}//返回新的购物车总量return num;} 3.增加购物车商品数量-控制层
✨3.1处理异常
else if(e instanceof CartNotFoundException) {result.setState(4007);result.setMessage(购物车数据不存在的异常);}
✨3.2设计请求 请求路径/carts/{cid}/num/add 请求方式POST 请求数据Integer cidHttpSession session 响应结果JsonResultInteger ✨3.3处理请求 RequestMapping({cid}/num/add)public JsonResultInteger addNum(Integer cid,HttpSession session){Integer data cartService.addNum(cid,getuidFromSession(session),getUsernameFromSession(session));return new JsonResult(OK,data);}
先登录在访问url地址对应的地址。 4.增加购物车商品数量-前端页面
1.前面已经在onclick中改过里面的内容所以无需重复修改了但是需要重新编写addNum()以确保点击后能够增加数量。
input classnum-btn typebutton value οnclickaddNum(#{cid}) / function addNum(cid){$.ajax({url: /carts/cid/num/add,type: POST,dataType: JSON,success: function (json) {if (json.state 200) {//先拿到数量展示的id$(#goodsCountcid).val(json.data)//由于price的值不是放在val控件上也不是放在某一个属性上通过html来拿//html就是拿到它标签内部的这个东西如果内部是个串拿到的就是个串//获取某个标签内部的内容文本、标签//因为刚好这个内容即:singlePrice作为一个子内容放在了开始和结束的中间let price $(#goodsPricecid).html();let totalPrice price * json.data;$(#goodsCastcid).html(totalPrice);} else {alert(增加购物车商品数量失败)}},error: function (xhr) {alert(增加购物车商品数量时产生未知的异常!xhr.message);}});}