使用的不是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";
}