1、創建相關類
domain:
Order
OrderItem
dao:OrderDao
service:OrderService
web.servlete:OrderServlet
1
2
3
4
5
6
7
8
9
10
|
/** * 訂單條目類 */ public class OrderItem { private String iid; private int count; // 數量 private double subtotal; // 小計 private Order order; // 所屬訂單 private Book book; // 所要購買的圖書 } |
1
2
3
4
5
6
7
8
9
10
11
12
13
|
/** * 訂單類 */ public class Order { private String oid; private Date ordertime; // 下單時間 private double total; // 合計 private int state; // 訂單狀態有四種:1未付款 2已付款但未發貨 3已發貨但未確認收貨 4已確認交易成功 private User owner; // 訂單所有者 private String address; // 收貨地址 private List<OrderItem> orderItemList; //當前訂單下所有條目 } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
|
public class OrderDao { private QueryRunner qr = new TxQueryRunner(); /** * 添加訂單 * @param order */ public void addOrder(Order order) { try { String sql = "insert into orders values(?,?,?,?,?,?)" ; /* * 處理util的Date轉換成sql的Timestamp */ Timestamp timestamp = new Timestamp(order.getOrdertime().getTime()); Object[] params = {order.getOid(), timestamp, order.getTotal(), order.getState(), order.getOwner().getUid(), order.getAddress()}; qr.update(sql, params); } catch(SQLException e) { throw new RuntimeException(e); } } /** * 插入訂單條目 * @param orderItemList */ public void addOrderItemList(List<OrderItem> orderItemList) { /** * QueryRunner類的batch(String sql, Object[][] params) * 其中params是多個一維數組! * 每個一維數組都與sql在一起執行一次,多個一維數組就執行多次 */ try { String sql = "insert into orderitem values(?,?,?,?,?)"; /* * 把orderItemList轉換成兩維數組 * 把一個OrderItem對象轉換成一個一維數組 */ Object[][] params = new Object[orderItemList.size()][]; // 循環遍歷orderItemList,使用每個orderItem對象為params中每個一維數組賦值 for(int i = 0; i < orderItemList.size(); i++) { OrderItem item = orderItemList.get(i); params[i] = new Object[]{item.getIid(), item.getCount(), item.getSubtotal(), item.getOrder().getOid(), item.getBook().getBid()}; } qr.batch(sql, params);//執行批處理 } catch(SQLException e) { throw new RuntimeException(e); } } /** * 按uid查詢訂單 * @param uid * @return */ public List<Order> findByUid(String uid) { /* * 1. 通過uid查詢出當前用戶的所有List<Order> * 2. 循環遍歷每個Order,為其加載他的所有OrderItem */ try { /* * 1. 得到當前用戶的所有訂單 */ String sql = "select * from orders where uid=?"; List<Order> orderList = qr.query(sql, new BeanListHandler<Order>(Order.class), uid); /* * 2. 循環遍歷每個Order,為其加載它自己所有的訂單條目 */ for(Order order : orderList) { loadOrderItems(order);//為order對象添加它的所有訂單條目 } /* * 3. 返回訂單列表 */ return orderList; } catch(SQLException e) { throw new RuntimeException(e); } } /** * 加載指定的訂單所有的訂單條目 * @param order * @throws SQLException */ private void loadOrderItems(Order order) throws SQLException { /* * 查詢兩張表:orderitem、book */ String sql = "select * from orderitem i, book b where i.bid=b.bid and oid=?"; /* * 因為一行結果集對應的不再是一個javabean,所以不能再使用BeanListHandler,而是MapListHandler */ List<Map<String,Object>> mapList = qr.query(sql, new MapListHandler(), order.getOid()); /* * mapList是多個map,每個map對應一行結果集 * 一行: * {iid=C7AD5492F27D492189105FB50E55CBB6, count=2, subtotal=60.0, oid=1AE8A70354C947F8B81B80ADA6783155, bid=7, bname=精通Hibernate,price=30.0, author=張衛琴, image=book_img/8991366-1_l.jpg, cid=2} * ... * * 我們需要使用一個Map生成兩個對象:OrderItem、Book,然后再建立兩者的關系(把Book設置給OrderItem) */ /* * 循環遍歷每個Map,使用map生成兩個對象,然后建立關系(最終結果一個OrderItem),把OrderItem保存起來 */ List<OrderItem> orderItemList = toOrderItemList(mapList); order.setOrderItemList(orderItemList); } /** * 把mapList中每個Map轉換成兩個對象,并建立關系 * @param mapList * @return */ private List<OrderItem> toOrderItemList(List<Map<String, Object>> mapList) { List<OrderItem> orderItemList = new ArrayList<OrderItem>(); for(Map<String,Object> map : mapList) { OrderItem item = toOrderItem(map); orderItemList.add(item); } return orderItemList; } /** * 把一個Map轉換成一個OrderItem對象 * @param map * @return */ private OrderItem toOrderItem(Map<String, Object> map) { OrderItem orderItem = CommonUtils.toBean(map, OrderItem.class); Book book = CommonUtils.toBean(map, Book.class); orderItem.setBook(book); return orderItem; } /** * 加載訂單 * @param oid * @return */ public Order load(String oid) { try { /* * 1. 得到當前用戶的所有訂單 */ String sql = "select * from orders where oid=?"; Order order = qr.query(sql, new BeanHandler<Order>(Order.class), oid); /* * 2. 為order加載它的所有條目 */ loadOrderItems(order); /* * 3. 返回訂單列表 */ return order; } catch(SQLException e) { throw new RuntimeException(e); } } /** * 通過oid查詢訂單狀態 * @param oid * @return */ public int getStateByOid(String oid) { try { String sql = "select state from orders where oid=?"; return (Integer)qr.query(sql, new ScalarHandler(), oid); } catch(SQLException e) { throw new RuntimeException(e); } } /** * 修改訂單狀態 * @param oid * @param state * @return */ public void updateState(String oid, int state) { try { String sql = "update orders set state=? where oid=?" ; qr.update(sql, state, oid); } catch (SQLException e) { throw new RuntimeException(e); } } } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
public class OrderService { private OrderDao orderDao = new OrderDao(); /** * 支付方法 * @param oid */ public void zhiFu(String oid) { /* * 1. 獲取訂單的狀態 * * 如果狀態為1,那么執行下面代碼 * * 如果狀態不為1,那么本方法什么都不做 */ int state = orderDao.getStateByOid(oid); if(state == 1) { // 修改訂單狀態為2 orderDao.updateState(oid, 2); } } /** * 添加訂單 * 需要處理事務 * @param order */ public void add(Order order) { try { // 開啟事務 JdbcUtils.beginTransaction(); orderDao.addOrder(order);//插入訂單 orderDao.addOrderItemList(order.getOrderItemList());//插入訂單中的所有條目 // 提交事務 JdbcUtils.commitTransaction(); } catch(Exception e) { // 回滾事務 try { JdbcUtils.rollbackTransaction(); } catch (SQLException e1) { } throw new RuntimeException(e); } } /** * 我的訂單 * @param uid * @return */ public List<Order> myOrders(String uid) { return orderDao.findByUid(uid); } /** * 加載訂單 * @param oid * @return */ public Order load(String oid) { return orderDao.load(oid); } /** * 確認收貨 * @param oid * @throws OrderException */ public void confirm(String oid) throws OrderException { /* * 1. 校驗訂單狀態,如果不是3,拋出異常 */ int state = orderDao.getStateByOid(oid);//獲取訂單狀態 if(state != 3) throw new OrderException("訂單確認失敗,您不是什么好東西!"); /* * 2. 修改訂單狀態為4,表示交易成功 */ orderDao.updateState(oid, 4 ); } } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
|
public class OrderServlet extends BaseServlet { private OrderService orderService = new OrderService(); /** * 支付之去銀行 * * @param request * @param response * @return * @throws ServletException * @throws IOException */ public String zhiFu(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Properties props = new Properties(); InputStream input = this .getClass().getClassLoader() .getResourceAsStream( "merchantInfo.properties" ); props.load(input); /* * 準備13參數 */ String p0_Cmd = "Buy"; String p1_MerId = props.getProperty("p1_MerId"); String p2_Order = request.getParameter("oid"); String p3_Amt = "0.01"; String p4_Cur = "CNY"; String p5_Pid = ""; String p6_Pcat = ""; String p7_Pdesc = ""; String p8_Url = props.getProperty("p8_Url"); String p9_SAF = ""; String pa_MP = ""; String pd_FrpId = request.getParameter("pd_FrpId"); String pr_NeedResponse = "1"; /* * 計算hmac */ String keyValue = props.getProperty("keyValue"); String hmac = PaymentUtil.buildHmac(p0_Cmd, p1_MerId, p2_Order, p3_Amt, p4_Cur, p5_Pid, p6_Pcat, p7_Pdesc, p8_Url, p9_SAF, pa_MP, pd_FrpId, pr_NeedResponse, keyValue); /* * 連接易寶的網址和13+1個參數 */ StringBuilder url = new StringBuilder(props.getProperty("url")); url.append("?p0_Cmd=").append(p0_Cmd); url.append("&p1_MerId=").append(p1_MerId); url.append("&p2_Order=").append(p2_Order); url.append("&p3_Amt=").append(p3_Amt); url.append("&p4_Cur=").append(p4_Cur); url.append("&p5_Pid=").append(p5_Pid); url.append("&p6_Pcat=").append(p6_Pcat); url.append("&p7_Pdesc=").append(p7_Pdesc); url.append("&p8_Url=").append(p8_Url); url.append("&p9_SAF=").append(p9_SAF); url.append("&pa_MP=").append(pa_MP); url.append("&pd_FrpId=").append(pd_FrpId); url.append("&pr_NeedResponse=").append(pr_NeedResponse); url.append("&hmac=").append(hmac); System.out.println(url); /* * 重定向到易寶 */ response.sendRedirect(url.toString()); return null; } /** * 這個方法是易寶回調方法 我們必須要判斷調用本方法的是不是易寶! * * @param request * @param response * @return * @throws ServletException * @throws IOException */ public String back(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { /* * 1. 獲取11 + 1 */ String p1_MerId = request.getParameter("p1_MerId"); String r0_Cmd = request.getParameter("r0_Cmd"); String r1_Code = request.getParameter("r1_Code"); String r2_TrxId = request.getParameter("r2_TrxId"); String r3_Amt = request.getParameter("r3_Amt"); String r4_Cur = request.getParameter("r4_Cur"); String r5_Pid = request.getParameter("r5_Pid"); String r6_Order = request.getParameter("r6_Order"); String r7_Uid = request.getParameter("r7_Uid"); String r8_MP = request.getParameter("r8_MP"); String r9_BType = request.getParameter("r9_BType"); String hmac = request.getParameter("hmac"); /* * 2. 校驗訪問者是否為易寶! */ Properties props = new Properties(); InputStream input = this.getClass().getClassLoader() .getResourceAsStream("merchantInfo.properties"); props.load(input); String keyValue = props.getProperty("keyValue"); boolean bool = PaymentUtil.verifyCallback(hmac, p1_MerId, r0_Cmd, r1_Code, r2_TrxId, r3_Amt, r4_Cur, r5_Pid, r6_Order, r7_Uid, r8_MP, r9_BType, keyValue); if(!bool) {//如果校驗失敗 request.setAttribute("msg", "您不是什么好東西!"); return "f:/jsps/msg.jsp"; } /* * 3. 獲取狀態訂單,確定是否要修改訂單狀態,以及添加積分等業務操作 */ orderService.zhiFu(r6_Order);//有可能對數據庫進行操作,也可能不操作! /* * 4. 判斷當前回調方式 * 如果為點對點,需要回饋以success開頭的字符串 */ if(r9_BType.equals("2")) { response.getWriter().print("success"); } /* * 5. 保存成功信息,轉發到msg.jsp */ request.setAttribute("msg", "支付成功!等待賣家發貨!你慢慢等~"); return "f:/jsps/msg.jsp"; } /** * 確認收貨 * * @param request * @param response * @return * @throws ServletException * @throws IOException */ public String confirm(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { /* * 1. 獲取oid參數 2. 調用service方法 > 如果有異常,保存異常信息,轉發到msg.jsp 3. * 保存成功信息,轉發到msg.jsp */ String oid = request.getParameter("oid"); try { orderService.confirm(oid); request.setAttribute("msg", "恭喜,交易成功!"); } catch (OrderException e) { request.setAttribute("msg", e.getMessage()); } return "f:/jsps/msg.jsp"; } /** * 加載訂單 * * @param request * @param response * @return * @throws ServletException * @throws IOException */ public String load(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { /* * 1. 得到oid參數 2. 使用oid調用service方法得到Order 3. * 保存到request域,轉發到/jsps/order/desc.jsp */ request.setAttribute("order", orderService.load(request.getParameter("oid"))); return "f:/jsps/order/desc.jsp"; } /** * 我的訂單 * * @param request * @param response * @return * @throws ServletException * @throws IOException */ public String myOrders(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { /* * 1. 從session得到當前用戶,再獲取其uid 2. * 使用uid調用orderService#myOrders(uid)得到該用戶的所有訂單List<Order> 3. * 把訂單列表保存到request域中,轉發到/jsps/order/list.jsp */ User user = (User) request.getSession().getAttribute("session_user"); List<Order> orderList = orderService.myOrders(user.getUid()); request.setAttribute("orderList", orderList); return "f:/jsps/order/list.jsp"; } /** * 添加訂單 把session中的車用來生成Order對象 * * @param request * @param response * @return * @throws ServletException * @throws IOException */ public String add(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { /* * 1. 從session中得到cart 2. 使用cart生成Order對象 3. 調用service方法完成添加訂單 4. * 保存order到request域中,轉發到/jsps/order/desc.jsp */ // 從session中獲取cart Cart cart = (Cart) request.getSession().getAttribute("cart"); // 把cart轉換成Order對象 /* * 創建Order對象,并設置屬性 * * Cart --> Order */ Order order = new Order(); order.setOid(CommonUtils.uuid());// 設置編號 order.setOrdertime(new Date());// 設置下單時間 order.setState(1);// 設置訂單狀態為1,表示未付款 User user = (User) request.getSession().getAttribute("session_user"); order.setOwner(user);// 設置訂單所有者 order.setTotal(cart.getTotal());// 設置訂單的合計,從cart中獲取合計 /* * 創建訂單條目集合 * * cartItemList --> orderItemList */ List<OrderItem> orderItemList = new ArrayList<OrderItem>(); // 循環遍歷Cart中的所有CartItem,使用每一個CartItem對象創建OrderItem對象,并添加到集合中 for (CartItem cartItem : cart.getCartItems()) { OrderItem oi = new OrderItem();// 創建訂單條目 oi.setIid(CommonUtils.uuid());// 設置條目的id oi.setCount(cartItem.getCount());// 設置條目的數量 oi.setBook(cartItem.getBook());// 設置條目的圖書 oi.setSubtotal(cartItem.getSubtotal());// 設置條目的小計 oi.setOrder(order);// 設置所屬訂單 orderItemList.add(oi);// 把訂單條目添加到集合中 } // 把所有的訂單條目添加到訂單中 order.setOrderItemList(orderItemList); // 清空購物車 cart.clear(); // //////////////////////////////////////////// /* * 3. 調用orderService添加訂單 */ orderService.add(order); /* * 4. 保存order到request域,轉發到/jsps/order/desc.jsp */ request.setAttribute( "order" , order); return "/jsps/order/desc.jsp" ; } } |
2、生成訂單
3、我的訂單(按用戶查)
4、加載訂單(按id查)
5、確認收貨
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。