javascript
SpringBoot电脑商城-购物车
購物車
- 1. 加入購物車
- 1.1 創(chuàng)建數(shù)據庫表
- 1.2 創(chuàng)建實體類
- 1.3 持久層
- 1.4 業(yè)務層
- 1.5 控制層
- 1.6 前端頁面
- 2. 顯示購物車
- 2.1 持久層
- 2.2 業(yè)務層
- 2.3 控制層
- 2.4 前端頁面
- 3. 增加購物車商品數(shù)量
- 3.1 持久層
- 3.2 業(yè)務層
- 3.3 控制層
- 3.4 前端頁面
- 4. 顯示勾選購物車數(shù)據
- 4.1 持久層
- 4.2 業(yè)務層
- 4.3 控制層
- 4.4 前端頁面
- 4.5 購物車頁面顯示收貨地址列表
1. 加入購物車
1.1 創(chuàng)建數(shù)據庫表
CREATE TABLE t_cart (cid INT AUTO_INCREMENT COMMENT '購物車數(shù)據id',uid INT NOT NULL COMMENT '用戶id',pid INT NOT NULL COMMENT '商品id',price BIGINT COMMENT '加入時商品單價',num INT COMMENT '商品數(shù)量',created_user VARCHAR(20) COMMENT '創(chuàng)建人',created_time DATETIME COMMENT '創(chuàng)建時間',modified_user VARCHAR(20) COMMENT '修改人',modified_time DATETIME COMMENT '修改時間',PRIMARY KEY (cid) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;1.2 創(chuàng)建實體類
public class Cart extends BaseEntity{private Integer cid;private Integer uid;private Integer pid ;private Long price;private Integer num;//...1.3 持久層
- 規(guī)劃需要執(zhí)行的SQL語句
1.向購物車表中插入數(shù)據insert into t_cart () values () 2.如果當前商品已經在購物車中存在,則直接更新num的數(shù)量即可。update t_cart set num = ? where cid=? 3.在插入或更新具體執(zhí)行哪個語句,取決于數(shù)據庫中是否有當前的這個購物車商品的數(shù)據,得去查詢才能確定。select * from t_cart where cid = ? and uid = ? - 設計接口和抽象方法
創(chuàng)建一個CartMapper接口持久層的文件。public interface CartMapper {//插入購物車數(shù)據Integer insert(Cart cart);//更新購物車某件商品的數(shù)量Integer updateNumByCid(Integer cid, Integer num,String modifiedUser, Date modifiedTime);//根據用戶的id和商品的id來查詢購物車的數(shù)據Cart findByUidAndPid(Integer uid, Integer pid); } - SQL映射
創(chuàng)建一個CartMapper.xml映射文件,添加以上三個抽象方法的SQL語句映射。<?xml version="1.0" encoding="UTF8" ?> <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.cy.store.mapper.CartMapper"><resultMap type="com.cy.store.entity.Cart" id="CartEntityMap"><id property="cid" column="cid"/><result property="createdUser" column="created_user"/><result property="createdTime" column="created_time"/><result property="modifiedUser" column="modified_user"/><result property="modifiedTime" column="modified_time"/></resultMap><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_cartsetnum=#{num}, modified_user=#{modifiedUser}, modified_time=#{modifiedTime}wherecid=#{cid}</update><select id="findByUidAndPid" resultMap="CartEntityMap">select * from t_cart where uid=#{uid} and pid=#{pid}</select></mapper> 測試@Autowired private CartMapper cartMapper;@Test public void insert(){Cart cart = new Cart();cart.setUid(10);cart.setPid(10000011);cart.setNum(2);cart.setPrice(1000L);cartMapper.insert(cart); }@Test public void updateNumByCid(){cartMapper.updateNumByCid(1,4,"張三", new Date()); }@Test public void findByUidAndPid() {System.out.println(cartMapper.findByUidAndPid(10, 10000011)); }
1.4 業(yè)務層
- 異常規(guī)劃
1.插入數(shù)據產生的異常:InsertException
2.更新數(shù)據產生的異常:UpdateException - 接口和抽象方法
創(chuàng)建一個ICartService接口文件public interface ICartService {/*** 添加商品到購物車* @param uid 用戶id* @param pid 商品id* @param amount 新增數(shù)量* @param username 用戶名(修改者)*/void addToCart(Integer uid, Integer pid, Integer amount, String username); } - 實現(xiàn)接口
創(chuàng)建一個CartServiceImpl的實現(xiàn)類@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 = new Cart();cart.setUid(uid);cart.setPid(pid);cart.setNum(amount);//補全價格,來自于商品中的數(shù)據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("插入數(shù)據時產生未知的異常");}} else { //表示當前的商品在購物車中已經存在,則更新到這條數(shù)據的num值Integer num = result.getNum() + amount;Integer rows = cartMapper.updateNumByCid(result.getCid(),num,username,date);if(rows != 1) {throw new UpdateException("更新數(shù)據時產生未知的異常");} } } 測試@Autowired private ICartService cartService;@Test public void addToCart() {cartService.addToCart(10,10000003,5,"管理員"); }
1.5 控制層
- 沒有需要處理的異常
- 設計請求處理/carts/add_to_cart get pid,amount,session JsonResult<Void>
- 完成請求處理方法的編寫。創(chuàng)建一個CartController類。@RequestMapping("carts") @RestController public class CartController extends BaseController{@Autowiredprivate 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);} } 先登錄再訪問進行測試:http://localhost:8080/carts/add_to_cart?pid=10000021&amount=5
1.6 前端頁面
在ajax函數(shù)中data參數(shù)的數(shù)據設置的方式:
- data: #("form表單選擇").serialize():用于參數(shù)比較多,并且表單的參數(shù)都需要提交
- data: new FormData($("form表單選擇")[0]):用于提交文件
- data: "username=Tom":用于參數(shù)值固定并且參數(shù)值列表有限
- 用JSON格式提交:data: {"username": "TOM","age": 18,"sex": 0 }
在product.html頁面,給[加入購物車]按鈕添加點擊事件,并發(fā)送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.state == 200) {alert("加入購物車成功");} else {alert("加入購物車失敗");}},error: function (xhr) {alert("加入購物車時產生未知的異常" + xhr.message);}}); });2. 顯示購物車
登錄后將對應用戶的購物車數(shù)據展示出來。
2.1 持久層
-
規(guī)劃SQL語句
selectcid,uid,pid,t_cart.price,t_cart.num,t_product.title,t_product.image,t_product.price as realPrice fromt_cart left join t_product on t_cart.pid = t_product.id where uid = ? order byt_cart.created_time desc;VO:Value Object,值對象。當進行select查詢時,查詢的結果屬于多張表中的內容,此時發(fā)現(xiàn)結果集不能直接使用某個pojo實體類來接收,pojo實體類不能包含多表查詢出來的結果。解決方式是:重新構建一個新的對象,這個對象用于存儲所查詢出來的結果集對應的映射,所以把這個對象稱之為 值對象。
在store包下創(chuàng)建一個vo包,在vo包下創(chuàng)建CartVO實體類:
/** 購物車數(shù)據的VO類 */ 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;//... -
設計接口
List<CartVO> findVOByUid(Integer uid);
在CartMapper接口中定義抽象方法 -
映射SQL
<select id="findVOByUid" resultType="com.cy.store.vo.CartVO">selectcid, uid, pid, t_cart.price, t_cart.num,t_product.title, t_product.image, t_product.price as realPricefromt_cart left join t_product on t_cart.pid = t_product.idwhereuid = #{uid}order byt_cart.created_time desc; </select>測試
@Test public void findVOByUid() {System.out.println(cartMapper.findVOByUid(10)); }
2.2 業(yè)務層
- 編寫業(yè)務層的接口方法List<CartVO> getVOByUid(Integer uid)
- 在實現(xiàn)類中實現(xiàn)此方法@Override public List<CartVO> getVOByUid(Integer uid) {return cartMapper.findVOByUid(uid); }
2.3 控制層
- 設計請求/carts/ session get JsonResult<List<CartVO>>
- 實現(xiàn)請求處理方法的代碼@RequestMapping({"","/"}) public JsonResult<List<CartVO>> getVOByUid(HttpSession session) {List<CartVO> data = cartService.getVOByUid(getuidFromSession(session));return new JsonResult<>(OK, data); } 先登錄再測試:http://localhost:8080/carts
2.4 前端頁面
1.注釋掉cart.js文件
<!-- <script src="../js/cart.js" type="text/javascript" charset="utf-8"></script> -->2.注意form表單結構。將“結算按鈕”改成type="button"屬性值。
3.ready()函數(shù)來完成自動的ajax請求的提交和處理。
3. 增加購物車商品數(shù)量
3.1 持久層
- 規(guī)劃需要執(zhí)行的SQL語句
1.執(zhí)行更新t_cart表記錄的num的值,無需重復開發(fā)。update t_cart set num = ?, modified_user = ?, modified_time = ? where cid = ?; 2.根據cid的值來查詢當前的購物車這條數(shù)據是否存在select * from t_cart where cid=#{cid} - 接口和抽象方法Cart findByCid(Integer cid);
- 配置SQL的映射<select id="findByCid">select * from t_cart where cid=#{cid}; </select> 測試@Test public void findByCid() {System.out.println(cartMapper.findByCid(1)); }
3.2 業(yè)務層
- 規(guī)劃異常
1.在更新時會產生更新異常
2.查詢的數(shù)據是否有訪問的權限
3.要查詢的數(shù)據不存在,拋出CartNotFoundException異常。 - 設計接口和抽象方法/*** 更新用戶的購物車數(shù)據的數(shù)量* @param cid* @param uid* @param username* @return 增加成功后新的數(shù)量*/ Integer addNum(Integer cid, Integer uid, String username);
- 實現(xiàn)方法@Override public Integer addNum(Integer cid, Integer uid, String username) {Cart result = cartMapper.findByCid(cid);if(result == null) {throw new CartNotFoundException("數(shù)據不存在");}if(!result.getUid().equals(uid)) {throw new AccessDeniedException("數(shù)據非法訪問");}Integer num = result.getNum() + 1;Integer rows = cartMapper.updateNumByCid(cid, num, username, new Date());if(rows != 1) {throw new UpdateException("更新數(shù)據失敗!");}return num; }
3.3 控制層
- 處理異常else if (e instanceof CartNotFoundException) {result.setState(4007);result.setMessage("購物車數(shù)據不存在的異常"); }
- 設計請求/carts/{cid}/num/add Integer cid, HttpSession post JsonResult<Integer>
- 處理請求@RequestMapping("{cid}/num/add") public JsonResult<Integer> addNum(@PathVariable("cid") Integer cid, HttpSession session) {Integer data = cartService.addNum(cid,getuidFromSession(session),getUsernameFromSession(session));return new JsonResult<>(OK, data); } 先登錄再訪問url:http://localhost:8080/carts/1/num/add
3.4 前端頁面
function addNum(cid) {$.ajax({url: "/carts/" + cid + "/num/add",type: "post",dataType: "JSON",success: function (json) {if(json.state == 200) {$("#goodsCount" + cid).val(json.data);let price = $("#goodsPrice" + cid).html();let totalPrice = price * json.data;$("#goodsCast" + cid).html(totalPrice);} else {alert("增加購物車數(shù)據失敗," + json.message);}},error: function (xhr) {alert("增加購物車商品數(shù)量產生未知的異常" + xhr.message);}}); }4. 顯示勾選購物車數(shù)據
4.1 持久層
- 規(guī)劃SQL語句
用戶在購物車列表頁中通過隨機勾選相關的商品,在點擊“結算”按鈕后,跳轉到結算頁面,在這個頁面中需要展示用戶在上個頁面所勾選的購物車對應的數(shù)據。兩個頁面需要用戶勾選的多個cid傳遞給下一個頁面。selectcid,uid,pid,t_cart.price,t_cart.num,t_product.title,t_product.image,t_product.price as realPrice fromt_cart left join t_product on t_cart.pid = t_product.id where cid in (?,?,?) order byt_cart.created_time desc; - 接口和抽象方法List<CartVO> findVOByCid(Integer[] cids);
- SQL映射<select id="findVOByCid" resultType="com.cy.store.vo.CartVO">selectcid, uid, pid, t_cart.price, t_cart.num,t_product.title, t_product.image, t_product.price as realPricefromt_cart left join t_product on t_cart.pid = t_product.idwherecid in (<foreach collection="array" item="cid" separator=",">#{cid}</foreach>)order byt_cart.created_time desc; </select> 測試@Test public void findVOByCid() {Integer[] cids = {1,2,3,4,30,20,40};System.out.println(cartMapper.findVOByCid(cids)); }
4.2 業(yè)務層
1.沒有需要進行異常的規(guī)劃
2.設計業(yè)務層接口中抽象方法
3.完成抽象方法的設計
@Override public List<CartVO> getVOByCid(Integer uid, Integer[] cids) {List<CartVO> list = cartMapper.findVOByCid(cids);Iterator<CartVO> it = list.iterator();while(it.hasNext()) {CartVO cartVO = it.next();if(!cartVO.getUid().equals(uid)) { //表示這個數(shù)據不屬于當前對象//從集合中移除這個數(shù)據list.remove(cartVO);}}return list; }4.3 控制層
1.請求設計
/carts/list Integer cids, HttpSession session post JsonResult<CartVO>2.完成請求處理方法的定義和聲明
@RequestMapping("list") public JsonResult<List<CartVO>> getVOByCid(Integer[] cids, HttpSession session) {List<CartVO> data = cartService.getVOByCid(getuidFromSession(session),cids);return new JsonResult<>(OK, data); }4.4 前端頁面
在cart.html中有個表單,點擊“結算”按鈕跳轉到這個頁面:action=“orderConfirm.html”。在orderConfirm.html頁面加入如下代碼,可以使頁面跳轉后就加載要結算的數(shù)據。
<script type="text/javascript">$(document).ready(function () {showCartList();});//展示購物車列表function showCartList() {//清空tbody標簽的數(shù)據$("#cart-list").empty();$.ajax({url: "/carts/list",type: "get",data: location.search.substr(1),dataType: "JSON",success: function (json) {if(json.state == 200) {let list= json.data;let allCount = 0;let allPrice = 0;for (let i = 0; i < list.length; i++) {let tr = '<tr>\n' +'<td><img src="..#{image}collect.png" class="img-responsive" /></td>\n' +'<td>#{title}</td>\n' +'<td>¥<span>#{price}</span></td>\n' +'<td>#{num}</td>\n' +'<td><span>#{totalPrice}</span></td>\n' +'</tr>';tr = tr.replace(/#{image}/g, list[i].image);tr = tr.replace(/#{title}/g, list[i].title);tr = tr.replace(/#{price}/g, list[i].price);tr = tr.replace(/#{num}/g, list[i].num);tr = tr.replace(/#{totalPrice}/g, list[i].price*list[i].num);$("#cart-list").append(tr);allCount += list[i].num;allPrice += list[i].price * list[i].num;}$("#all-count").html(allCount);$("#all-price").html(allPrice);}},error: function (xhr) {alert("購物袋列表數(shù)據加載產生未知的異常" + xhr.status);}});} </script>注:這里有個bug,當你什么都不勾選就去結算,會報錯。因為controller中是需要接收參數(shù)的,但是沒勾選就提交是沒有帶參數(shù)的,這就有問題了。所以最好在結算的時候判斷一下有沒有選擇商品。
4.5 購物車頁面顯示收貨地址列表
1.收獲地址存放在一個select下拉列表中,將查詢到的當前登錄用戶的收貨地址動態(tài)的加載到這個下拉列表中。從數(shù)據庫的角度,是一個select查詢語句。已經編寫了根據用戶的uid來查詢當前用戶的收貨地址數(shù)據。
2.orderConfirm.html頁面中,收貨地址數(shù)據的展示需要自動進行加載,需要將方法的邏輯放在ready()函數(shù)中。
3.聲明和定義showAddressList()方法,方法中發(fā)送ajax請求即可。
function showAddressList() {//清空tbody標簽的數(shù)據$("#address-list").empty();$.ajax({url: "/addresses/",type: "get",dataType: "JSON",success: function (json) {if(json.state == 200) {let list= json.data;for (let i = 0; i < list.length; i++) {let opt = "<option value='#{aid}'>#{name} #{tag} #{provinceName}#{cityName}#{areaName}#{address} #{phone}</option>";opt = opt.replace(/#{aid}/g, list[i].aid);opt = opt.replace(/#{name}/g, list[i].name);opt = opt.replace(/#{tag}/g, list[i].tag);opt = opt.replace(/#{provinceName}/g, list[i].provinceName);opt = opt.replace(/#{cityName}/g, list[i].cityName);opt = opt.replace(/#{areaName}/g, list[i].areaName);opt = opt.replace(/#{address}/g, list[i].address);opt = opt.replace(/#{phone}/g, list[i].phone);$("#address-list").append(opt);}}},error: function (xhr) {alert("購物車收貨地址加載產生未知的異常" + xhr.status);}}); }總結
以上是生活随笔為你收集整理的SpringBoot电脑商城-购物车的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java Object类型的参数
- 下一篇: 低功耗抗噪 高抗干扰6路6通道6键触摸触