使用的不是session,也不是cookie,而是表
> 添加購物條目 > 修改購物條目的數量 > 刪除條目 > 批量刪除條目 > 我的購物車,即按用戶查詢條目 > 查詢勾選的條目
1:數據表
insert into `t_cartitem`(`cartItemId`,`quantity`,`bid`,`uid`,`orderBy`) values ('B8939FC55131469CAB11E3924D40185B',1,'CE01F15D435A4C51B0AD8202A318DCA7','xxx',11);
2.CartItem
1 public class CartItem { 2 private String cartItemId;// 主鍵 3 private int quantity;// 數量 4 private Book book;// 條目對應的圖書 5 private User user;// 所屬用戶 6 7 // 添加小計方法 8 public double getSubtotal() { 9 /* 10 * 使用BigDecimal不會有誤差 11 * 要求必須使用String類型構造器 12 */ 13 BigDecimal b1 = new BigDecimal(book.getCurrPrice() + ""); 14 BigDecimal b2 = new BigDecimal(quantity + ""); 15 BigDecimal b3 = b1.multiply(b2); 16 return b3.doubleValue(); 17 } 18 19 public String getCartItemId() { 20 return cartItemId; 21 } 22 23 public void setCartItemId(String cartItemId) { 24 this.cartItemId = cartItemId; 25 } 26 27 public int getQuantity() { 28 return quantity; 29 } 30 31 public void setQuantity(int quantity) { 32 this.quantity = quantity; 33 } 34 35 public Book getBook() { 36 return book; 37 } 38 39 public void setBook(Book book) { 40 this.book = book; 41 } 42 43 public User getUser() { 44 return user; 45 } 46 47 public void setUser(User user) { 48 this.user = user; 49 } 50 }CartItem 小技巧:Java中四捨五入 BigDecimal不會有誤差
// 添加小計方法 public double getSubtotal() { /* * 使用BigDecimal不會有誤差 * 要求必須使用String類型構造器 */ BigDecimal b1 = new BigDecimal(book.getCurrPrice() + ""); BigDecimal b2 = new BigDecimal(quantity + ""); BigDecimal b3 = b1.multiply(b2); return b3.doubleValue(); }
3.通過用戶查詢購物車條目
我的購物車條目中每個條目需要顯示圖書的圖片 書名 單價 ,這說明需要多表查詢
public List<CartItem> findByUser(String uid) throws SQLException { String sql = "select * from t_cartitem c, t_book b where c.bid=b.bid and uid=? order by c.orderBy"; List<Map<String,Object>> mapList = qr.query(sql, new MapListHandler(), uid); return toCartItemList(mapList); }
4.添加購物車條目----增
jsp
<div class="divForm"> <form id="form1" action="<c:url value='/CartItemServlet'/>" method="post"> <input type="hidden" name="method" value="add"/> <input type="hidden" name="bid" value="${book.bid }"/> 我要買:<input id="cnt">public String add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { /* * 1. 封裝表單數據到CartItem(bid, quantity) */ Map map = req.getParameterMap(); CartItem cartItem = CommonUtils.toBean(map, CartItem.class); Book book = CommonUtils.toBean(map, Book.class); User user = (User)req.getSession().getAttribute("sessionUser"); cartItem.setBook(book); cartItem.setUser(user); cartItemService.add(cartItem); return myCart(req, resp); }
CartItemService
public void add(CartItem cartItem) { try { /* * 1. 使用uid和bid去數據庫中查詢這個條目是否存在 */ CartItem _cartItem = cartItemDao.findByUidAndBid( cartItem.getUser().getUid(), cartItem.getBook().getBid()); if(_cartItem == null) {//如果原來沒有這個條目,那麼添加條目 cartItem.setCartItemId(CommonUtils.uuid()); cartItemDao.addCartItem(cartItem); } else {//如果原來有這個條目,修改數量 // 使用原有數量和新條目數量之各,來做為新的數量 int quantity = cartItem.getQuantity() + _cartItem.getQuantity(); // 修改這個老條目的數量 cartItemDao.updateQuantity(_cartItem.getCartItemId(), quantity); } } catch(Exception e) { throw new RuntimeException(e); } }
CartItemDao
public void addCartItem(CartItem cartItem) throws SQLException { String sql = "insert into t_cartitem(cartItemId, quantity, bid, uid)" + " values(?,?,?,?)"; Object[] params = {cartItem.getCartItemId(), cartItem.getQuantity(), cartItem.getBook().getBid(), cartItem.getUser().getUid()}; qr.update(sql, params); }
5.購物車模塊頁面javascript----查
計算總計
給全選添加click事件
給所有條目的復選框添加click事件
給減號添加click事件
給加號添加click事件
批量刪除
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 3 <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%> 4 5 6 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 7 <html> 8 <head> 9 <title>cartlist.jsp</title> 10 11 <meta http-equiv="pragma" content="no-cache"> 12 <meta http-equiv="cache-control" content="no-cache"> 13 <meta http-equiv="expires" content="0"> 14 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> 15 <meta http-equiv="description" content="This is my page"> 16 <!-- 17 <link rel="stylesheet" type="text/css" href="styles.css"> 18 --> 19 <script src="<c:url value='/jquery/jquery-1.5.1.js'/>"></script> 20 <script src="<c:url value='/js/round.js'/>"></script> 21 22 <link rel="stylesheet" type="text/css" href="<c:url value='/jsps/css/cart/list.css'/>"> 23 <script type="text/javascript"> 24 $(function() { 25 showTotal();//計算總計 26 27 /* 28 給全選添加click事件 29 */ 30 $("#selectAll").click(function() { 31 /* 32 1. 獲取全選的狀態 33 */ 34 var bool = $("#selectAll").attr("checked"); 35 /* 36 2. 讓所有條目的復選框與全選的狀態同步 37 */ 38 setItemCheckBox(bool); 39 /* 40 3. 讓結算按鈕與全選同步 41 */ 42 setJieSuan(bool); 43 /* 44 4. 重新計算總計 45 */ 46 showTotal(); 47 }); 48 49 /* 50 給所有條目的復選框添加click事件 51 */ 52 $(":checkbox[name=checkboxBtn]").click(function() { 53 var all = $(":checkbox[name=checkboxBtn]").length;//所有條目的個數 54 var select = $(":checkbox[name=checkboxBtn][checked=true]").length;//獲取所有被選擇條目的個數 55 56 if(all == select) {//全都選中了 57 $("#selectAll").attr("checked", true);//勾選全選復選框 58 setJieSuan(true);//讓結算按鈕有效 59 } else if(select == 0) {//誰都沒有選中 60 $("#selectAll").attr("checked", false);//取消全選 61 setJieSuan(false);//讓結算失效 62 } else { 63 $("#selectAll").attr("checked", false);//取消全選 64 setJieSuan(true);//讓結算有效 65 } 66 showTotal();//重新計算總計 67 }); 68 69 /* 70 給減號添加click事件 71 */ 72 $(".jian").click(function() { 73 // 獲取cartItemId 74 var id = $(this).attr("id").substring(0, 32); 75 // 獲取輸入框中的數量 76 var quantity = $("#" + id + "Quantity").val(); 77 // 判斷當前數量是否為1,如果為1,那就不是修改數量了,而是要刪除了。 78 if(quantity == 1) { 79 if(confirm("您是否真要刪除該條目?")) { 80 location = "/goods/CartItemServlet?method=batchDelete&cartItemIds=" + id; 81 } 82 } else { 83 sendUpdateQuantity(id, quantity-1); 84 } 85 }); 86 87 // 給加號添加click事件 88 $(".jia").click(function() { 89 // 獲取cartItemId 90 var id = $(this).attr("id").substring(0, 32); 91 // 獲取輸入框中的數量 92 var quantity = $("#" + id + "Quantity").val(); 93 sendUpdateQuantity(id, Number(quantity)+1); 94 }); 95 }); 96 97 // 請求服務器,修改數量。 98 function sendUpdateQuantity(id, quantity) { 99 $.ajax({ 100 async:false, 101 cache:false, 102 url:"/goods/CartItemServlet", 103 data:{method:"updateQuantity",cartItemId:id,quantity:quantity}, 104 type:"POST", 105 dataType:"json", 106 success:function(result) { 107 //1. 修改數量 108 $("#" + id + "Quantity").val(result.quantity); 109 //2. 修改小計 110 $("#" + id + "Subtotal").text(result.subtotal); 111 //3. 重新計算總計 112 showTotal(); 113 } 114 }); 115 } 116 117 /* 118 * 計算總計 119 */ 120 function showTotal() { 121 var total = 0; 122 /* 123 1. 獲取所有的被勾選的條目復選框!循環遍歷之 124 */ 125 $(":checkbox[name=checkboxBtn][checked=true]").each(function() { 126 //2. 獲取復選框的值,即其他元素的前綴 127 var id = $(this).val(); 128 //3. 再通過前綴找到小計元素,獲取其文本 129 var text = $("#" + id + "Subtotal").text(); 130 //4. 累加計算 131 total += Number(text); 132 }); 133 // 5. 把總計顯示在總計元素上 134 $("#total").text(round(total, 2));//round()函數的作用是把total保留2位 135 } 136 137 /* 138 * 統一設置所有條目的復選按鈕 139 */ 140 function setItemCheckBox(bool) { 141 $(":checkbox[name=checkboxBtn]").attr("checked", bool); 142 } 143 144 /* 145 * 設置結算按鈕樣式 146 */ 147 function setJieSuan(bool) { 148 if(bool) { 149 $("#jiesuan").removeClass("kill").addClass("jiesuan"); 150 $("#jiesuan").unbind("click");//撤消當前元素止所有click事件 151 } else { 152 $("#jiesuan").removeClass("jiesuan").addClass("kill"); 153 $("#jiesuan").click(function() {return false;}); 154 } 155 156 } 157 158 /* 159 * 批量刪除 160 */ 161 function batchDelete() { 162 // 1. 獲取所有被選中條目的復選框 163 // 2. 創建一數組,把所有被選中的復選框的值添加到數組中 164 // 3. 指定location為CartItemServlet,參數method=batchDelete,參數cartItemIds=數組的toString() 165 var cartItemIdArray = new Array(); 166 $(":checkbox[name=checkboxBtn][checked=true]").each(function() { 167 cartItemIdArray.push($(this).val());//把復選框的值添加到數組中 168 }); 169 location = "/goods/CartItemServlet?method=batchDelete&cartItemIds=" + cartItemIdArray; 170 } 171 172 /* 173 * 結算 174 */ 175 function jiesuan() { 176 // 1. 獲取所有被選擇的條目的id,放到數組中 177 var cartItemIdArray = new Array(); 178 $(":checkbox[name=checkboxBtn][checked=true]").each(function() { 179 cartItemIdArray.push($(this).val());//把復選框的值添加到數組中 180 }); 181 // 2. 把數組的值toString(),然後賦給表單的cartItemIds這個hidden 182 $("#cartItemIds").val(cartItemIdArray.toString()); 183 // 把總計的值,也保存到表單中 184 $("#hiddenTotal").val($("#total").text()); 185 // 3. 提交這個表單 186 $("#jieSuanForm").submit(); 187 } 188 </script> 189 </head> 190 <body> 191 192 <c:choose> 193 <c:when test="${empty cartItemList }"> 194 <table width="95%" align="center" cellpadding="0" cellspacing="0"> 195 <tr> 196 <td align="right"> 197 <img align="top" src="<c:url value='/images/icon_empty.png'/>"/> 198 </td> 199 <td> 200 <span class="spanEmpty">您的購物車中暫時沒有商品</span> 201 </td> 202 </tr> 203 </table> 204 </c:when> 205 <c:otherwise> 206 <table width="95%" align="center" cellpadding="0" cellspacing="0"> 207 <tr align="center" bgcolor="#efeae5"> 208 <td align="left" width="50px"> 209 <input type="checkbox" id="selectAll" checked="checked"/><label for="selectAll">全選</label> 210 </td> 211 <td colspan="2">商品名稱</td> 212 <td>單價</td> 213 <td>數量</td> 214 <td>小計</td> 215 <td>操作</td> 216 </tr> 217 218 219 220 <c:forEach items="${cartItemList }" var="cartItem"> 221 <tr align="center"> 222 <td align="left"> 223 <input value="${cartItem.cartItemId }" type="checkbox" name="checkboxBtn" checked="checked"/> 224 </td> 225 <td align="left" width="70px"> 226 <a class="linkImage" href="<c:url value='/jsps/book/desc.jsp'/>"><img border="0" width="54" align="top" src="<c:url value='/${cartItem.book.image_b }'/>"/></a> 227 </td> 228 <td align="left" width="400px"> 229 <a href="<c:url value='/jsps/book/desc.jsp'/>"><span>${cartItem.book.bname }</span></a> 230 </td> 231 <td><span>¥<span class="currPrice">${cartItem.book.currPrice }</span></span></td> 232 <td> 233 <a class="jian" id="${cartItem.cartItemId }Jian"></a><input class="quantity" readonly="readonly" id="${cartItem.cartItemId }Quantity" type="text" value="${cartItem.quantity }"/><a class="jia" id="${cartItem.cartItemId }Jia"></a> 234 </td> 235 <td width="100px"> 236 <span class="price_n">¥<span class="subTotal" id="${cartItem.cartItemId }Subtotal">${cartItem.subtotal }</span></span> 237 </td> 238 <td> 239 <a href="<c:url value='/CartItemServlet?method=batchDelete&cartItemIds=${cartItem.cartItemId }'/>">刪除</a> 240 </td> 241 </tr> 242 </c:forEach> 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 <tr> 263 <td colspan="4" class="tdBatchDelete"> 264 <a href="javascript:batchDelete();">批量刪除</a> 265 </td> 266 <td colspan="3" align="right" class="tdTotal"> 267 <span>總計:</span><span class="price_t">¥<span id="total"></span></span> 268 </td> 269 </tr> 270 <tr> 271 <td colspan="7" align="right"> 272 <a href="javascript:jiesuan();" id="jiesuan" class="jiesuan"></a> 273 </td> 274 </tr> 275 </table> 276 <form id="jieSuanForm" action="<c:url value='/CartItemServlet'/>" method="post"> 277 <input type="hidden" name="cartItemIds" id="cartItemIds"/> 278 <input type="hidden" name="total" id="hiddenTotal"/> 279 <input type="hidden" name="method" value="loadCartItems"/> 280 </form> 281 282 </c:otherwise> 283 </c:choose> 284 </body> 285 </html>list.jsp
小技巧:js中四捨五入round.js
// 5. 把總計顯示在總計元素上 $("#total").text(round(total, 2));//round()函數的作用是把total保留2位
1 function round(num,dec){ 2 var strNum = num + '';/*把要轉換的小數轉換成字符串*/ 3 var index = strNum.indexOf("."); /*獲取小數點的位置*/ 4 if(index < 0) { 5 return num;/*如果沒有小數點,那麼無需四捨五入,返回這個整數*/ 6 } 7 var n = strNum.length - index -1;/*獲取當前浮點數,小數點後的位數*/ 8 if(dec < n){ 9 /*把小數點向後移動要保留的位數,把需要保留的小數部分變成整數部分,只留下不需要保留的部分為小數*/ 10 var e = Math.pow(10, dec); 11 num = num * e; 12 /*進行四捨五入,只保留整數部分*/ 13 num = Math.round(num); 14 /*再把原來小數部分還原為小數*/ 15 return num / e; 16 } else { 17 return num;/*如果當前小數點後的位數等於或小於要保留的位數,那麼無需處理,直接返回*/ 18 } 19 }round.js
6.批量刪除功能----刪
jsp
function batchDelete() { // 1. 獲取所有被選中條目的復選框 // 2. 創建一數組,把所有被選中的復選框的值添加到數組中 // 3. 指定location為CartItemServlet,參數method=batchDelete,參數cartItemIds=數組的toString() var cartItemIdArray = new Array(); $(":checkbox[name=checkboxBtn][checked=true]").each(function() { cartItemIdArray.push($(this).val());//把復選框的值添加到數組中 }); location = "/goods/CartItemServlet?method=batchDelete&cartItemIds=" + cartItemIdArray; }
刪除一個
if(quantity == 1) { if(confirm("您是否真要刪除該條目?")) { location = "/goods/CartItemServlet?method=batchDelete&cartItemIds=" + id; } } else {
7.修改數量----改
jsp
// 請求服務器,修改數量。 function sendUpdateQuantity(id, quantity) { $.ajax({ async:false, cache:false, url:"/goods/CartItemServlet", data:{method:"updateQuantity",cartItemId:id,quantity:quantity}, type:"POST", dataType:"json", success:function(result) { //1. 修改數量 $("#" + id + "Quantity").val(result.quantity); //2. 修改小計 $("#" + id + "Subtotal").text(result.subtotal); //3. 重新計算總計 showTotal(); } }); }
servlet
public String updateQuantity(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String cartItemId = req.getParameter("cartItemId"); int quantity = Integer.parseInt(req.getParameter("quantity")); CartItem cartItem = cartItemService.updateQuantity(cartItemId, quantity); // 給客戶端返回一個json對象 StringBuilder sb = new StringBuilder("{"); sb.append("\"quantity\"").append(":").append(cartItem.getQuantity()); sb.append(","); sb.append("\"subtotal\"").append(":").append(cartItem.getSubtotal()); sb.append("}"); resp.getWriter().print(sb); return null; }
8.結算
jsp
<form id="jieSuanForm" action="<c:url value='/CartItemServlet'/>" method="post"> <input type="hidden" name="cartItemIds" id="cartItemIds"/> <input type="hidden" name="total" id="hiddenTotal"/> <input type="hidden" name="method" value="loadCartItems"/> </form> function jiesuan() { // 1. 獲取所有被選擇的條目的id,放到數組中 var cartItemIdArray = new Array(); $(":checkbox[name=checkboxBtn][checked=true]").each(function() { cartItemIdArray.push($(this).val());//把復選框的值添加到數組中 }); // 2. 把數組的值toString(),然後賦給表單的cartItemIds這個hidden $("#cartItemIds").val(cartItemIdArray.toString()); // 把總計的值,也保存到表單中 $("#hiddenTotal").val($("#total").text()); // 3. 提交這個表單 $("#jieSuanForm").submit(); }
servlet
public String loadCartItems(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { /* * 1. 獲取cartItemIds參數 */ String cartItemIds = req.getParameter("cartItemIds"); double total = Double.parseDouble(req.getParameter("total")); /* * 2. 通過service得到List<CartItem> */ List<CartItem> cartItemList = cartItemService.loadCartItems(cartItemIds); /* * 3. 保存,然後轉發到/cart/showitem.jsp */ req.setAttribute("cartItemList", cartItemList); req.setAttribute("total", total); req.setAttribute("cartItemIds", cartItemIds); return "f:/jsps/cart/showitem.jsp"; }