├── .classpath ├── .gitignore ├── .project ├── .settings ├── .jsdtscope ├── org.eclipse.core.resources.prefs ├── org.eclipse.jdt.core.prefs ├── org.eclipse.wst.common.component ├── org.eclipse.wst.common.project.facet.core.xml ├── org.eclipse.wst.jsdt.ui.superType.container └── org.eclipse.wst.jsdt.ui.superType.name ├── LICENSE ├── README.md ├── WebContent ├── META-INF │ └── MANIFEST.MF ├── WEB-INF │ ├── lib │ │ ├── c3p0-0.9.1.2.jar │ │ ├── commons-dbutils-1.3.jar │ │ ├── gson-2.2.4.jar │ │ ├── jstl.jar │ │ ├── mysql-connector-java-5.1.7-bin.jar │ │ └── standard.jar │ ├── pages │ │ ├── cart.jsp │ │ ├── cash.jsp │ │ ├── computer.jsp │ │ ├── computers.jsp │ │ ├── emptycart.jsp │ │ └── trades.jsp │ └── web.xml ├── commons │ ├── footer.jsp │ ├── header.jsp │ └── queryCondition.jsp ├── error-1.jsp ├── index.jsp ├── public │ ├── css │ │ ├── bootstrap.min.css │ │ ├── bootstrapValidator.css │ │ ├── cart.css │ │ └── index.css │ ├── fonts │ │ ├── glyphicons-halflings-regular.eot │ │ ├── glyphicons-halflings-regular.svg │ │ ├── glyphicons-halflings-regular.ttf │ │ ├── glyphicons-halflings-regular.woff │ │ └── glyphicons-halflings-regular.woff2 │ ├── img │ │ ├── 1.jpg │ │ ├── mac.png │ │ └── zard.jpg │ └── js │ │ ├── bootstrap.min.js │ │ ├── cartValidate.js │ │ └── jquery-3.2.1.min.js └── success.jsp ├── estore.sql └── src ├── c3p0-config.xml └── com └── xmut └── estore ├── dao ├── AccountDAO.java ├── ComputerDAO.java ├── Dao.java ├── TradeDAO.java ├── TradeItemDAO.java ├── UserDAO.java └── impl │ ├── AccountDAOIml.java │ ├── BaseDAO.java │ ├── ComputerDAOImpl.java │ ├── TradeDAOImpl.java │ ├── TradeItemDAOImpl.java │ └── UserDAOImpl.java ├── db └── JDBCUtils.java ├── domain ├── Account.java ├── Computer.java ├── ShoppingCart.java ├── ShoppingCartItem.java ├── Trade.java ├── TradeItem.java └── User.java ├── exception └── DBException.java ├── filter ├── EncodingFilter.java └── TranactionFilter.java ├── service ├── AccountService.java ├── ComputerService.java └── UserService.java ├── servlet ├── ComputerServlet.java └── UserServlet.java ├── test ├── BaseDAOTest.java └── ComputerDAOTest.java ├── utils └── ReflectionUtils.java └── web ├── ConnectionContext.java ├── CriteriaComputer.java ├── EStoreWebUtils.java └── Page.java /.classpath: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # idea 2 | \.idea/ 3 | *.iml 4 | # eclipse 5 | 6 | \.settings/ 7 | 8 | # maven 9 | target/ 10 | *.class -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | Estore 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.wst.common.project.facet.core.builder 15 | 16 | 17 | 18 | 19 | org.eclipse.wst.validation.validationbuilder 20 | 21 | 22 | 23 | 24 | 25 | org.eclipse.jem.workbench.JavaEMFNature 26 | org.eclipse.wst.common.modulecore.ModuleCoreNature 27 | org.eclipse.wst.common.project.facet.core.nature 28 | org.eclipse.jdt.core.javanature 29 | org.eclipse.wst.jsdt.core.jsNature 30 | 31 | 32 | -------------------------------------------------------------------------------- /.settings/.jsdtscope: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding//WebContent/commons/header.jsp=UTF-8 3 | -------------------------------------------------------------------------------- /.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 4 | org.eclipse.jdt.core.compiler.compliance=1.8 5 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 6 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 7 | org.eclipse.jdt.core.compiler.source=1.8 8 | -------------------------------------------------------------------------------- /.settings/org.eclipse.wst.common.component: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.settings/org.eclipse.wst.common.project.facet.core.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /.settings/org.eclipse.wst.jsdt.ui.superType.container: -------------------------------------------------------------------------------- 1 | org.eclipse.wst.jsdt.launching.baseBrowserLibrary -------------------------------------------------------------------------------- /.settings/org.eclipse.wst.jsdt.ui.superType.name: -------------------------------------------------------------------------------- 1 | Window -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 hsingyin 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # EStore百脑汇 2 | 3 | # 一、起步 4 | - ### 简介 5 | 6 | 一个基于JavaWeb的网上电子城项目,这个项目可以熟悉MVC开发模式,方便以后学习SSM等技术 7 | 8 | - ### 使用技术 9 | * IDE:Eclipse 10 | * 数据库:MySQL 11 | * 数据源:C3P0 12 | * JDBC 工具:DBUtils 13 | * 前端框架:Bootstrap 14 | * Ajax 解决方案:jQuery + JavaScript + JSON + google-gson 15 | 16 | - ### 快速上手 17 | - 在你的MySQL中创建一个名为estore的数据库(字符编码gb2312),导入使用我提供的estore.sql 18 | - 使用eclipse导入项目 19 | - 用到的jar包在WEB-INF/lib目录下,记得添加tomcat的jar包,build path即可 20 | - 修改src/c3p0-config.xml中的数据库账号密码 21 | - 在eclipse中配置好tomcat,run on server即可 22 | 23 | 24 | # 二、预览 25 | 26 | 27 | 28 | ### 1、首页 29 | 30 | ![](https://i.imgur.com/2yIrtBL.png) 31 | 32 | ### 2、分页 33 | 34 | ![](https://i.imgur.com/IuFmvYt.png) 35 | 36 | ### 3、范围筛选 37 | 38 | ![](https://i.imgur.com/35SjE32.png) 39 | 40 | ### 4、购物车 41 | 42 | ![](https://i.imgur.com/5bczaKm.png) 43 | 44 | ### 5、结账 45 | 46 | ![](https://i.imgur.com/xPb2N4m.png) 47 | 48 | # 三、升级建议 49 | 50 | > 因为时间问题没来得及增加和完善的功能和页面,可能会在之后提交更新,在此之前大家可以自己完善 51 | 52 | - 完善收藏功能 53 | 54 | ![](https://i.imgur.com/od9lZb4.png) 55 | 56 | - 重写商品详情页 57 | 58 | - 增加登陆注册功能 59 | 60 | - 增加个人中心功能 61 | 62 | ![](https://i.imgur.com/YijyssV.png) 63 | 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /WebContent/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Class-Path: 3 | 4 | -------------------------------------------------------------------------------- /WebContent/WEB-INF/lib/c3p0-0.9.1.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsingyin/EStore/cce20e2288bb0bbccff17b66bf3b126b5f7564c2/WebContent/WEB-INF/lib/c3p0-0.9.1.2.jar -------------------------------------------------------------------------------- /WebContent/WEB-INF/lib/commons-dbutils-1.3.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsingyin/EStore/cce20e2288bb0bbccff17b66bf3b126b5f7564c2/WebContent/WEB-INF/lib/commons-dbutils-1.3.jar -------------------------------------------------------------------------------- /WebContent/WEB-INF/lib/gson-2.2.4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsingyin/EStore/cce20e2288bb0bbccff17b66bf3b126b5f7564c2/WebContent/WEB-INF/lib/gson-2.2.4.jar -------------------------------------------------------------------------------- /WebContent/WEB-INF/lib/jstl.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsingyin/EStore/cce20e2288bb0bbccff17b66bf3b126b5f7564c2/WebContent/WEB-INF/lib/jstl.jar -------------------------------------------------------------------------------- /WebContent/WEB-INF/lib/mysql-connector-java-5.1.7-bin.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsingyin/EStore/cce20e2288bb0bbccff17b66bf3b126b5f7564c2/WebContent/WEB-INF/lib/mysql-connector-java-5.1.7-bin.jar -------------------------------------------------------------------------------- /WebContent/WEB-INF/lib/standard.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsingyin/EStore/cce20e2288bb0bbccff17b66bf3b126b5f7564c2/WebContent/WEB-INF/lib/standard.jar -------------------------------------------------------------------------------- /WebContent/WEB-INF/pages/cart.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" contentType="text/html; charset=UTF-8" 2 | pageEncoding="UTF-8"%> 3 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 4 | <% 5 | String jsUrl=request.getContextPath()+"/public/js/"; 6 | String cssUrl=request.getContextPath()+"/public/css/"; 7 | String imgUrl=request.getContextPath()+"/public/img/"; 8 | %> 9 | 10 | 11 | 12 | 13 | 购物车 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | <%@ include file="/commons/queryCondition.jsp" %> 22 | 23 | 24 | <%@ include file="/commons/header.jsp"%> 25 | 26 | 27 | 28 | 29 |

30 |
31 |
32 |
您的购物车中共有 ${sessionScope.ShoppingCart.computerNumber } 件商品
33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 48 | 51 | 52 | 55 | 56 | 57 | 58 | 59 |
商品名数量价格操作
45 | ${item.computer.id } 46 | ${item.computer.brand }   ${item.computer.model } 47 | 49 | 50 | ${item.computer.price } 53 | 删除 54 |
60 | 61 | 62 |
总金额:¥ ${sessionScope.ShoppingCart.totalMoney } 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 | <%@ include file="/commons/footer.jsp"%> 94 | 95 | -------------------------------------------------------------------------------- /WebContent/WEB-INF/pages/cash.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" contentType="text/html; charset=UTF-8" 2 | pageEncoding="UTF-8"%> 3 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 4 | <% 5 | String jsUrl=request.getContextPath()+"/public/js/"; 6 | String cssUrl=request.getContextPath()+"/public/css/"; 7 | String imgUrl=request.getContextPath()+"/public/img/"; 8 | String flieUrl = request.getContextPath()+"/WEB-INF/pages/"; 9 | %> 10 | 11 | 12 | 13 | 14 | 结账 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | <%@ include file="/commons/queryCondition.jsp" %> 26 | 27 | 28 | <%@ include file="/commons/header.jsp"%> 29 | 30 |
31 |

32 | 33 |
34 | 35 |
36 | 37 | 您一共买了 ${sessionScope.ShoppingCart.computerNumber } 件商品 38 | 应付: ¥ ${ sessionScope.ShoppingCart.totalMoney} 39 | 40 |
41 | 42 | 43 | 44 |
45 | 46 | ${requestScope.errors } 47 |
48 | 49 |
50 | 51 | 52 |
53 | 62 |
63 | 64 |
65 | 66 | 67 | 68 | <%@ include file="/commons/footer.jsp"%> 69 | 70 | -------------------------------------------------------------------------------- /WebContent/WEB-INF/pages/computer.jsp: -------------------------------------------------------------------------------- 1 | <%@page import="org.apache.jasper.tagplugins.jstl.core.Param"%> 2 | <%@ page language="java" contentType="text/html; charset=UTF-8" 3 | pageEncoding="UTF-8"%> 4 | <% 5 | String jsUrl=request.getContextPath()+"/public/js/"; 6 | String cssUrl=request.getContextPath()+"/public/css/"; 7 | String imgUrl=request.getContextPath()+"/public/img/"; 8 | %> 9 | 10 | 11 | 12 | 13 | 商品详情 ${computer.model} 14 | 15 | 16 | 17 | 18 | 19 | 20 | <%@ include file="/commons/queryCondition.jsp" %> 21 | 22 | 23 | 24 | 25 | <%@ include file="/commons/header.jsp"%> 26 | 27 |
28 |
29 | 30 |
31 |
32 |

33 | 品牌:${computer.brand} 34 |

35 | 型号: ${computer.model } 36 |

37 | 价格: ¥ ${computer.price } 38 |

39 | 发布时间: ${computer.publishingDate } 40 |

41 | 商品备注: ${computer.remark } 42 |

43 | 44 | 继续购物 45 | 加入购物车 46 |
47 | 48 |
49 | <%@ include file="/commons/footer.jsp"%> 50 | 51 | -------------------------------------------------------------------------------- /WebContent/WEB-INF/pages/computers.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" contentType="text/html; charset=UTF-8" 2 | pageEncoding="UTF-8"%> 3 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 4 | <% 5 | String jsUrl=request.getContextPath()+"/public/js/"; 6 | String cssUrl=request.getContextPath()+"/public/css/"; 7 | String imgUrl=request.getContextPath()+"/public/img/"; 8 | %> 9 | 10 | 11 | 12 | 13 | 14 | 15 | estore百脑汇--只卖正品,顺丰包邮 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 59 | 68 | <%@ include file="/commons/queryCondition.jsp" %> 69 | 70 | 71 | <%@ include file="/commons/header.jsp"%> 72 | 73 | 74 | 75 | 76 |
77 | 78 | 79 |
80 | 81 | 成功!您已经将 ${param.brand } ${param.model} 加入到购物车中! 82 | 立即查看购物车 83 |
84 | 85 |
86 | 87 |
88 | 89 | 90 | 91 | 107 |
108 |
109 | 110 | 111 | 112 | 128 | 129 | 130 |
131 | 132 | 133 |
134 | 共 ${computerpage.totalPageNumber } 页 135 |    136 | 当前第 ${computerpage.pageNo } 页 137 |    138 | 139 | 140 | 首页 141 |    142 | 上一页 143 | 144 | 145 |    146 | 147 | 148 | 下一页 149 |    150 | 末页 151 | 152 | 153 |    154 | 155 | 转到 页 156 |
157 | 158 | 159 |
160 | <%@ include file="/commons/footer.jsp"%> 161 | 162 | 163 | 164 | 165 | 166 | -------------------------------------------------------------------------------- /WebContent/WEB-INF/pages/emptycart.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" contentType="text/html; charset=UTF-8" 2 | pageEncoding="UTF-8"%> 3 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 4 | <% 5 | String jsUrl=request.getContextPath()+"/public/js/"; 6 | String cssUrl=request.getContextPath()+"/public/css/"; 7 | String imgUrl=request.getContextPath()+"/public/img/"; 8 | %> 9 | 10 | 11 | 12 | 13 | 购物车 14 | 15 | 16 | 17 | 18 | 19 | 20 | <%@ include file="/commons/queryCondition.jsp" %> 21 | 22 | 23 | 24 | <%@ include file="/commons/header.jsp"%> 25 | 26 |
27 |
28 | 29 |

购物车空空如也~

30 |

返回

31 |
32 |
33 | 34 | 35 | 36 | 37 | <%@ include file="/commons/footer.jsp"%> 38 | 39 | -------------------------------------------------------------------------------- /WebContent/WEB-INF/pages/trades.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" contentType="text/html; charset=UTF-8" 2 | pageEncoding="UTF-8"%> 3 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 4 | <% 5 | String jsUrl=request.getContextPath()+"/public/js/"; 6 | String cssUrl=request.getContextPath()+"/public/css/"; 7 | String imgUrl=request.getContextPath()+"/public/img/"; 8 | %> 9 | 10 | 11 | 12 | 13 | 。。 14 | 15 | 16 | 17 | 18 | 19 | 20 | <%@ include file="/commons/queryCondition.jsp" %> 21 | 22 | 23 | <%@ include file="/commons/header.jsp"%> 24 |
25 |

26 |

User: ${user.username }

27 | 28 |

29 | 30 | 31 | 32 | 33 | 53 | 54 | 55 | 56 |
34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 |
TradTime: ${trade.tradeTime }
${item.computer.model }${item.computer.price }${item.quantity }
51 |

52 |
57 | 58 |
59 | <%@ include file="/commons/footer.jsp"%> 60 | 61 | -------------------------------------------------------------------------------- /WebContent/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Estore 4 | 5 | index.html 6 | index.htm 7 | index.jsp 8 | default.html 9 | default.htm 10 | default.jsp 11 | 12 | 13 | encoding 14 | UTF-8 15 | 16 | 17 | 18 | ComputerServlet 19 | ComputerServlet 20 | com.xmut.estore.servlet.ComputerServlet 21 | 22 | 23 | ComputerServlet 24 | /computerServlet 25 | 26 | 27 | EncodingFilter 28 | EncodingFilter 29 | com.xmut.estore.filter.EncodingFilter 30 | 31 | 32 | EncodingFilter 33 | /* 34 | 35 | 36 | TranactionFilter 37 | TranactionFilter 38 | com.xmut.estore.filter.TranactionFilter 39 | 40 | 41 | TranactionFilter 42 | /* 43 | 44 | 45 | 46 | UserServlet 47 | UserServlet 48 | com.xmut.estore.servlet.UserServlet 49 | 50 | 51 | UserServlet 52 | /userServlet 53 | 54 | -------------------------------------------------------------------------------- /WebContent/commons/footer.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" contentType="text/html; charset=UTF-8" 2 | pageEncoding="UTF-8"%> 3 | 4 |
5 | -------------------------------------------------------------------------------- /WebContent/commons/header.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" contentType="text/html; charset=UTF-8" 2 | pageEncoding="UTF-8"%> 3 | 4 | -------------------------------------------------------------------------------- /WebContent/commons/queryCondition.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" contentType="text/html; charset=UTF-8" 2 | pageEncoding="UTF-8"%> 3 | 4 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /WebContent/error-1.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" contentType="text/html; charset=UTF-8" 2 | pageEncoding="UTF-8"%> 3 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 4 | <% 5 | String jsUrl=request.getContextPath()+"/public/js/"; 6 | String cssUrl=request.getContextPath()+"/public/css/"; 7 | String imgUrl=request.getContextPath()+"/public/img/"; 8 | %> 9 | 10 | 11 | 12 | 13 | 404错误 14 | 15 | 16 | 17 | 18 | 19 | 20 | <%@ include file="/commons/queryCondition.jsp" %> 21 | 22 | 23 | 24 | <%@ include file="/commons/header.jsp"%> 25 | 26 |
27 |
28 |

404!页面未能够找到

29 |

抱歉,页面好像去火星啦!

30 |

返回

31 |
32 |
33 | 34 | 35 | 36 | 37 | <%@ include file="/commons/footer.jsp"%> 38 | 39 | -------------------------------------------------------------------------------- /WebContent/index.jsp: -------------------------------------------------------------------------------- 1 | <% 2 | response.sendRedirect(request.getContextPath()+"/computerServlet?method=getComputers"); 3 | %> -------------------------------------------------------------------------------- /WebContent/public/css/bootstrapValidator.css: -------------------------------------------------------------------------------- 1 | /** 2 | * BootstrapValidator (http://bootstrapvalidator.com) 3 | * The best jQuery plugin to validate form fields. Designed to use with Bootstrap 3 4 | * 5 | * @author http://twitter.com/nghuuphuoc 6 | * @copyright (c) 2013 - 2014 Nguyen Huu Phuoc 7 | * @license Commercial: http://bootstrapvalidator.com/license/ 8 | * Non-commercial: http://creativecommons.org/licenses/by-nc-nd/3.0/ 9 | */ 10 | 11 | .bv-form .help-block { 12 | margin-bottom: 0; 13 | } 14 | .bv-form .tooltip-inner { 15 | text-align: left; 16 | } 17 | .nav-tabs li.bv-tab-success > a { 18 | color: #3c763d; 19 | } 20 | .nav-tabs li.bv-tab-error > a { 21 | color: #a94442; 22 | } 23 | 24 | .bv-form .bv-icon-no-label { 25 | top: 0; 26 | } 27 | 28 | .bv-form .bv-icon-input-group { 29 | top: 0; 30 | z-index: 100; 31 | } -------------------------------------------------------------------------------- /WebContent/public/css/cart.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | .table tbody tr td{ 3 | vertical-align: middle; 4 | } 5 | .cartItemNum { 6 | 7 | text-align:center; 8 | } 9 | .totalMoney { 10 | font-size:22px; 11 | } 12 | -------------------------------------------------------------------------------- /WebContent/public/css/index.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | body{ 3 | width:100%; 4 | height:100%; 5 | min-height:100%; 6 | } 7 | a, 8 | a:hover{ 9 | text-decoration:none; 10 | } 11 | .navbar { 12 | margin-bottom:0px; 13 | } 14 | .tips { 15 | width:100%; 16 | height: 75px; 17 | } 18 | .tip-success { 19 | 20 | text-align: center; 21 | 22 | } 23 | .priceSelect { 24 | width:100px; 25 | } 26 | .searchBox{ 27 | width:600px; 28 | margin-bottom:20px; 29 | line-height:34px; 30 | } 31 | .prcieNum { 32 | font-weight: bold; 33 | font-size: 22px; 34 | color: #f40; 35 | 36 | } 37 | 38 | .addToCart{ 39 | background:#f40; 40 | border:#f40; 41 | } 42 | .searchBtn { 43 | 44 | background:#f40; 45 | border:#f40; 46 | } 47 | .addToCart:hover{ 48 | background:#F22D00; 49 | border:#F22D00; 50 | } 51 | .searchBtn:hover{ 52 | background:#F22D00; 53 | border:#F22D00; 54 | } 55 | .thumbnail { 56 | 57 | } 58 | .cartItem { 59 | height:200px; 60 | line-height: 200px; 61 | } 62 | #back-to-top { 63 | float:right; 64 | cursor:pointer 65 | } 66 | .footer { 67 | 68 | } -------------------------------------------------------------------------------- /WebContent/public/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsingyin/EStore/cce20e2288bb0bbccff17b66bf3b126b5f7564c2/WebContent/public/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /WebContent/public/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsingyin/EStore/cce20e2288bb0bbccff17b66bf3b126b5f7564c2/WebContent/public/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /WebContent/public/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsingyin/EStore/cce20e2288bb0bbccff17b66bf3b126b5f7564c2/WebContent/public/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /WebContent/public/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsingyin/EStore/cce20e2288bb0bbccff17b66bf3b126b5f7564c2/WebContent/public/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /WebContent/public/img/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsingyin/EStore/cce20e2288bb0bbccff17b66bf3b126b5f7564c2/WebContent/public/img/1.jpg -------------------------------------------------------------------------------- /WebContent/public/img/mac.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsingyin/EStore/cce20e2288bb0bbccff17b66bf3b126b5f7564c2/WebContent/public/img/mac.png -------------------------------------------------------------------------------- /WebContent/public/img/zard.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hsingyin/EStore/cce20e2288bb0bbccff17b66bf3b126b5f7564c2/WebContent/public/img/zard.jpg -------------------------------------------------------------------------------- /WebContent/public/js/bootstrap.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v3.3.7 (http://getbootstrap.com) 3 | * Copyright 2011-2016 Twitter, Inc. 4 | * Licensed under the MIT license 5 | */ 6 | if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1||b[0]>3)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){if(a(b.target).is(this))return b.handleObj.handler.apply(this,arguments)}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.7",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a("#"===f?[]:f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.7",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c).prop(c,!0)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c).prop(c,!1))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")?(c.prop("checked")&&(a=!1),b.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==c.prop("type")&&(c.prop("checked")!==this.$element.hasClass("active")&&(a=!1),this.$element.toggleClass("active")),c.prop("checked",this.$element.hasClass("active")),a&&c.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target).closest(".btn");b.call(d,"toggle"),a(c.target).is('input[type="radio"], input[type="checkbox"]')||(c.preventDefault(),d.is("input,button")?d.trigger("focus"):d.find("input:visible,button:visible").first().trigger("focus"))}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.7",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));if(!(a>this.$items.length-1||a<0))return this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){if(!this.sliding)return this.slide("next")},c.prototype.prev=function(){if(!this.sliding)return this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle="collapse"][href="#'+b.id+'"],[data-toggle="collapse"][data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.7",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":e.data();c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function c(c){c&&3===c.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=b(d),f={relatedTarget:this};e.hasClass("open")&&(c&&"click"==c.type&&/input|textarea/i.test(c.target.tagName)&&a.contains(e[0],c.target)||(e.trigger(c=a.Event("hide.bs.dropdown",f)),c.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger(a.Event("hidden.bs.dropdown",f)))))}))}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.7",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=b(e),g=f.hasClass("open");if(c(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(a(this)).on("click",c);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger(a.Event("shown.bs.dropdown",h))}return!1}},g.prototype.keydown=function(c){if(/(38|40|27|32)/.test(c.which)&&!/input|textarea/i.test(c.target.tagName)){var d=a(this);if(c.preventDefault(),c.stopPropagation(),!d.is(".disabled, :disabled")){var e=b(d),g=e.hasClass("open");if(!g&&27!=c.which||g&&27==c.which)return 27==c.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.disabled):visible a",i=e.find(".dropdown-menu"+h);if(i.length){var j=i.index(c.target);38==c.which&&j>0&&j--,40==c.which&&jdocument.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth
',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(a.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusin"==b.type?"focus":"hover"]=!0),c.tip().hasClass("in")||"in"==c.hoverState?void(c.hoverState="in"):(clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.isInStateTrue=function(){for(var a in this.inState)if(this.inState[a])return!0;return!1},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);if(c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusout"==b.type?"focus":"hover"]=!1),!c.isInStateTrue())return clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide()},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.getPosition(this.$viewport);h="bottom"==h&&k.bottom+m>o.bottom?"top":"top"==h&&k.top-mo.width?"left":"left"==h&&k.left-lg.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;jg.right&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){if(!this.$tip&&(this.$tip=a(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),b?(c.inState.click=!c.inState.click,c.isInStateTrue()?c.enter(c):c.leave(c)):c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type),a.$tip&&a.$tip.detach(),a.$tip=null,a.$arrow=null,a.$viewport=null,a.$element=null})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;!e&&/destroy|hide/.test(b)||(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.7",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:''}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.7",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c="offset",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c="position",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data("target")||b.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b=e[a]&&(void 0===e[a+1]||b .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.7",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return e=a-d&&"bottom"},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=Math.max(a(document).height(),a(document.body).height());"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery); -------------------------------------------------------------------------------- /WebContent/public/js/cartValidate.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | 5 | 6 | $(function(){ 7 | $(".delete").click(function(){ 8 | 9 | var $tr = $(this).parent().parent(); 10 | var title = $.trim($tr.find("td:first").text()); 11 | var flag = confirm("确定要删除" + title + "吗?"); 12 | 13 | if(flag){ 14 | return true; 15 | } 16 | 17 | return false; 18 | }); 19 | 20 | //ajax 修改单个商品的数量: 21 | //1. 获取页面中所有的 text, 并为其添加 onchange 响应函数. 弹出确认对话框: 确定要修改吗? 22 | $(":text").change(function(){ 23 | var quantityVal = $.trim(this.value); 24 | 25 | var flag = false; 26 | 27 | var reg = /^\d+$/g; 28 | var quantity = -1; 29 | if(reg.test(quantityVal)){ 30 | quantity = parseInt(quantityVal); 31 | if(quantity >= 0){ 32 | flag = true; 33 | } 34 | } 35 | 36 | if(!flag){ 37 | alert("输入的数量不合法!"); 38 | $(this).val($(this).attr("step")); 39 | return; 40 | } 41 | 42 | var $tr = $(this).parent().parent(); 43 | var title = $.trim($tr.find("td:first").text()); 44 | 45 | if(quantity == 0){ 46 | var flag2 = confirm("确定要删除" + title + "吗?"); 47 | if(flag2){ 48 | //得到了 a 节点 49 | var $a = $tr.find("td:last").find("a"); 50 | //执行 a 节点的 onclick 响应函数. 51 | $a[0].onclick(); 52 | 53 | return; 54 | } 55 | } 56 | 57 | var flag = confirm("确定要修改" + title + "的数量吗?"); 58 | 59 | if(!flag){ 60 | $(this).val($(this).attr("class")); 61 | return; 62 | } 63 | //2. 请求地址为: computerServlet 64 | var url = "computerServlet"; 65 | 66 | //3. 请求参数为: method:updateItemQuantity, id:name属性值, quantity:val, time:new Date() 67 | var idVal = $.trim(this.name); 68 | var args = {"method":"updateItemQuantity", "id":idVal, "quantity":quantityVal, "time":new Date()}; 69 | 70 | //4. 在 updateItemQuantity 方法中, 获取 quanity, id, 再获取购物车对象, 调用 service 的方法做修改 71 | //5. 传回 JSON 数据: computerNumber:xx, totalMoney 72 | 73 | //6. 更新当前页面的 computerNumber 和 totalMoney 74 | $.post(url, args, function(data){ 75 | var computerNumber = data.computerNumber; 76 | var totalMoney = data.totalMoney; 77 | 78 | $("#totalMoney").text("总金额:¥ " + totalMoney); 79 | $("#computerNumber").text("您的购物车中共有" + computerNumber + "件商品"); 80 | },"JSON"); 81 | 82 | }); 83 | 84 | }) 85 | 86 | -------------------------------------------------------------------------------- /WebContent/success.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" contentType="text/html; charset=UTF-8" 2 | pageEncoding="UTF-8"%> 3 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 4 | <% 5 | String jsUrl=request.getContextPath()+"/public/js/"; 6 | String cssUrl=request.getContextPath()+"/public/css/"; 7 | String imgUrl=request.getContextPath()+"/public/img/"; 8 | %> 9 | 10 | 11 | 12 | 13 | 404错误 14 | 15 | 16 | 17 | 18 | 19 | 20 | <%@ include file="/commons/queryCondition.jsp" %> 21 | 22 | 23 | 24 | <%@ include file="/commons/header.jsp"%> 25 | 26 |
27 |
28 |

操作成功

29 |

${computer.brand}

30 |

返回

31 |
32 |
33 | 34 | 35 | 36 | 37 | <%@ include file="/commons/footer.jsp"%> 38 | 39 | -------------------------------------------------------------------------------- /estore.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Navicat MySQL Data Transfer 3 | 4 | Source Server : localhost 5 | Source Server Version : 50720 6 | Source Host : localhost:3306 7 | Source Database : estore 8 | 9 | Target Server Type : MYSQL 10 | Target Server Version : 50720 11 | File Encoding : 65001 12 | 13 | Date: 2018-01-20 10:48:04 14 | */ 15 | 16 | SET FOREIGN_KEY_CHECKS=0; 17 | 18 | -- ---------------------------- 19 | -- Table structure for account 20 | -- ---------------------------- 21 | DROP TABLE IF EXISTS `account`; 22 | CREATE TABLE `account` ( 23 | `accountid` int(11) NOT NULL AUTO_INCREMENT, 24 | `balance` float DEFAULT NULL, 25 | PRIMARY KEY (`accountid`) 26 | ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=gb2312; 27 | 28 | -- ---------------------------- 29 | -- Records of account 30 | -- ---------------------------- 31 | INSERT INTO `account` VALUES ('1', '-4711'); 32 | 33 | -- ---------------------------- 34 | -- Table structure for mycomputers 35 | -- ---------------------------- 36 | DROP TABLE IF EXISTS `mycomputers`; 37 | CREATE TABLE `mycomputers` ( 38 | `Id` int(100) NOT NULL AUTO_INCREMENT, 39 | `Brand` varchar(255) NOT NULL, 40 | `Model` varchar(255) NOT NULL, 41 | `Price` float NOT NULL, 42 | `Publishingdate` date NOT NULL, 43 | `Salesamount` int(255) NOT NULL, 44 | `Storenumber` int(255) NOT NULL, 45 | `Remark` text, 46 | `Url` varchar(255) DEFAULT NULL, 47 | PRIMARY KEY (`Id`) 48 | ) ENGINE=InnoDB AUTO_INCREMENT=33 DEFAULT CHARSET=gb2312; 49 | 50 | -- ---------------------------- 51 | -- Records of mycomputers 52 | -- ---------------------------- 53 | INSERT INTO `mycomputers` VALUES ('1', 'Lenovo/联想', '拯救者R720', '6399', '2009-06-22', '2', '0', '', 'https://img14.360buyimg.com/n0/jfs/t15049/87/1663809259/215478/4effd883/5a54725aNc2bfede3.jpg'); 54 | INSERT INTO `mycomputers` VALUES ('2', 'Lenovo/联想', 'IdeaPad520', '7788', '2009-06-22', '3', '1', '', 'https://img14.360buyimg.com/n0/jfs/t15577/77/15567626/68061/bcb650da/5a250d6dN5021fd39.jpg'); 55 | INSERT INTO `mycomputers` VALUES ('3', 'Lenovo/联想', '小新潮7000', '5799', '2009-06-22', '3', '3', '', 'https://img14.360buyimg.com/n0/jfs/t10366/269/1156861319/249444/b4748f86/59ddb6a1Nab0db15a.jpg'); 56 | INSERT INTO `mycomputers` VALUES ('4', 'Lenovo/联想', '扬天V110', '5466', '2009-06-22', '99', '86', '', 'https://img14.360buyimg.com/n0/jfs/t11665/144/1977363093/148875/2afebfe2/5a102166N24669fb0.jpg'); 57 | INSERT INTO `mycomputers` VALUES ('5', 'Lenovo/联想', '天逸310', '4878', '2009-06-22', '3', '100', '', 'https://img14.360buyimg.com/n0/jfs/t11137/61/317409326/206620/795ce1df/59ed8b95N45d478aa.jpg'); 58 | INSERT INTO `mycomputers` VALUES ('6', 'Lenovo/联想', 'YOGA710', '4547', '2009-06-22', '3', '100', '', 'https://img14.360buyimg.com/n0/jfs/t3793/114/394282152/175032/419db602/58089d25N0529144e.jpg'); 59 | INSERT INTO `mycomputers` VALUES ('7', 'Lenovo/联想', '灵耀S4000UA', '8755', '2009-06-22', '2', '12', '', 'https://img14.360buyimg.com/n0/jfs/t14599/47/1719827073/241151/1842b1bf/5a558428Nac6701f8.jpg'); 60 | INSERT INTO `mycomputers` VALUES ('8', '华硕', '飞行堡垒四代', '5577', '2009-06-22', '2', '13', '', 'https://img14.360buyimg.com/n0/jfs/t12373/136/2098321220/289540/a78cf3ae/5a322179N5ad65368.jpg'); 61 | INSERT INTO `mycomputers` VALUES ('9', '华硕', '傲世V241', '5678', '2009-06-22', '3', '16', '', 'https://img14.360buyimg.com/n0/jfs/t15721/192/153946165/323073/f1632294/5a289d75Na52414f1.jpg'); 62 | INSERT INTO `mycomputers` VALUES ('10', '华硕', '顽石FL8000', '7558', '2009-06-22', '3', '17', '', 'https://img14.360buyimg.com/n0/jfs/t14809/116/1353021633/238143/dc984dee/5a4db56fN05526605.jpg'); 63 | INSERT INTO `mycomputers` VALUES ('11', '华硕', '灵焕3', '4577', '2009-06-22', '9', '17', '', 'https://img10.360buyimg.com/n1/s450x450_jfs/t12430/308/203140737/205408/d6357060/5a0562fcN93f86b13.jpg'); 64 | INSERT INTO `mycomputers` VALUES ('12', '华硕', '灵耀3', '8877', '2009-06-22', '9', '19', '', 'https://img14.360buyimg.com/n0/jfs/t11557/254/2470034939/232568/deae5003/5a18200dN6c3b9ee0.jpg'); 65 | INSERT INTO `mycomputers` VALUES ('13', '华硕', '灵耀U4000', '6677', '2009-06-22', '6', '14', '', 'https://img14.360buyimg.com/n0/jfs/t13522/11/2081039894/95185/e7c394d6/5a3231fbN8ba41527.jpg'); 66 | INSERT INTO `mycomputers` VALUES ('14', 'TinkPad', 'E470c', '4688', '2009-06-22', '9', '12', '', 'https://img14.360buyimg.com/n0/jfs/t16357/52/866540934/261455/2b01e587/5a434797N1299bda3.jpg'); 67 | INSERT INTO `mycomputers` VALUES ('15', 'TinkPad', 'New S2', '7899', '2009-06-22', '8', '14', '', 'https://img14.360buyimg.com/n0/jfs/t15187/253/1057049023/225106/a06a6722/5a435c85Na46f2823.jpg'); 68 | INSERT INTO `mycomputers` VALUES ('16', 'TinkPad', '翼480', '7887', '2009-06-22', '8', '23', '', 'https://img14.360buyimg.com/n0/jfs/t14920/22/1777379314/198740/95d0cc64/5a582c82N56109a34.jpg'); 69 | INSERT INTO `mycomputers` VALUES ('17', 'TinkPad', '黑侠E570', '5565', '2009-06-22', '7', '24', '', 'https://img14.360buyimg.com/n0/jfs/t16117/219/863344336/280658/6d765e35/5a436902N52254c4e.jpg'); 70 | INSERT INTO `mycomputers` VALUES ('18', 'TinkPad', 'E560', '7897', '2009-06-22', '8', '25', '', 'https://img14.360buyimg.com/n0/jfs/t8452/195/381457995/270920/bbd530eb/59a659a3N09b0c621.jpg'); 71 | INSERT INTO `mycomputers` VALUES ('19', 'TinkPad', 'X270', '7867', '2009-06-22', '7', '26', '', 'https://img14.360buyimg.com/n0/jfs/t14878/106/1055955167/194749/ea6d39/5a43391cN7b9165d1.jpg'); 72 | INSERT INTO `mycomputers` VALUES ('20', 'TinkPad', 'T470', '4545', '2009-06-22', '10', '26', '', 'https://img14.360buyimg.com/n0/jfs/t14971/132/1050352559/252493/c8f294cd/5a43398fNc7239122.jpg'); 73 | INSERT INTO `mycomputers` VALUES ('21', 'TinkPad', 'X1 Carbon 2017', '5778', '2009-06-22', '5', '28', '', 'https://img14.360buyimg.com/n0/jfs/t14143/58/1306436672/166146/b84e7109/5a43480dNb102e5ff.jpg'); 74 | INSERT INTO `mycomputers` VALUES ('22', 'TinkPad', '黑将S5 2017', '7475', '2009-06-22', '5', '24', '', 'https://img14.360buyimg.com/n0/jfs/t16294/264/579247137/262391/c0311d8d/5a3680e4N1556b858.jpg'); 75 | INSERT INTO `mycomputers` VALUES ('23', '戴尔', '灵越燃7000', '3685', '2009-06-22', '5', '25', '', 'https://img14.360buyimg.com/n0/jfs/t10453/85/2217094050/260610/bc7201c5/59f15b82Nae0ef9f3.jpg'); 76 | INSERT INTO `mycomputers` VALUES ('24', '戴尔', '灵越7570-R1745S', '5578', '2009-06-22', '5', '26', '', 'https://img14.360buyimg.com/n0/jfs/t7339/186/3433212847/202495/313b3cc3/59f15e0fN58d66eb2.jpg'); 77 | INSERT INTO `mycomputers` VALUES ('25', '戴尔', '灵越游匣Master15', '4566', '2009-06-22', '4', '32', '', 'https://img14.360buyimg.com/n0/jfs/t15823/200/670885287/314599/b194c717/5a3a230eN2f84896a.jpg'); 78 | INSERT INTO `mycomputers` VALUES ('26', '戴尔', '灵越飞匣14ER', '7378', '2009-06-22', '4', '33', '', 'https://img14.360buyimg.com/n0/jfs/t11875/342/853551087/286947/90b41858/59f99027N0c041a4a.jpg'); 79 | INSERT INTO `mycomputers` VALUES ('27', '戴尔', 'XPS13', '7454', '2009-06-22', '3', '34', '', 'https://img14.360buyimg.com/n0/jfs/t7537/177/3956737992/398920/2304bd9c/59f1587aN48a06866.jpg'); 80 | INSERT INTO `mycomputers` VALUES ('28', '戴尔', 'XPS15', '10999', '2009-06-22', '4', '35', '', 'https://img14.360buyimg.com/n0/jfs/t13837/321/719476245/393033/3c005d85/5a128bb1N3da985b9.jpg'); 81 | INSERT INTO `mycomputers` VALUES ('29', '戴尔', '成就5000', '7645', '2009-06-22', '5', '36', '', 'https://img14.360buyimg.com/n0/jfs/t13597/123/1502382470/248417/4c3428c4/5a20fb62N4072b9a3.jpg'); 82 | INSERT INTO `mycomputers` VALUES ('30', '戴尔', '灵越5280', '7777', '2009-06-22', '5', '100', '', 'https://img14.360buyimg.com/n0/jfs/t12214/281/2361720574/192008/7a2408d6/5a3b7a19N7aabf636.jpg'); 83 | INSERT INTO `mycomputers` VALUES ('31', '戴尔', '成就3565', '4578', '2009-06-22', '7', '99', '', 'https://img14.360buyimg.com/n0/jfs/t9367/329/1374059840/297787/cd35add8/59c07459N3b30049c.jpg'); 84 | INSERT INTO `mycomputers` VALUES ('32', '戴尔', '成就5459', '7956', '2009-06-22', '7', '100', '', 'https://img14.360buyimg.com/n0/jfs/t10633/340/2610639484/232696/c43b4120/59f98fd7Nccba81ec.jpg'); 85 | 86 | -- ---------------------------- 87 | -- Table structure for trade 88 | -- ---------------------------- 89 | DROP TABLE IF EXISTS `trade`; 90 | CREATE TABLE `trade` ( 91 | `tradeid` int(11) NOT NULL AUTO_INCREMENT, 92 | `userid` int(11) NOT NULL, 93 | `tradetime` datetime NOT NULL, 94 | PRIMARY KEY (`tradeid`), 95 | KEY `user_id_fk` (`userid`), 96 | CONSTRAINT `trade_ibfk_1` FOREIGN KEY (`userid`) REFERENCES `userinfo` (`userid`) 97 | ) ENGINE=InnoDB AUTO_INCREMENT=37 DEFAULT CHARSET=gb2312; 98 | 99 | -- ---------------------------- 100 | -- Records of trade 101 | -- ---------------------------- 102 | INSERT INTO `trade` VALUES ('12', '1', '2012-11-01 00:00:00'); 103 | INSERT INTO `trade` VALUES ('13', '1', '2012-11-01 00:00:00'); 104 | INSERT INTO `trade` VALUES ('14', '1', '2012-11-01 00:00:00'); 105 | INSERT INTO `trade` VALUES ('15', '1', '2012-12-20 00:00:00'); 106 | INSERT INTO `trade` VALUES ('16', '1', '2012-12-20 00:00:00'); 107 | INSERT INTO `trade` VALUES ('17', '1', '2018-01-16 00:00:00'); 108 | INSERT INTO `trade` VALUES ('18', '3', '2018-01-16 00:00:00'); 109 | INSERT INTO `trade` VALUES ('19', '2', '2018-01-16 00:00:00'); 110 | INSERT INTO `trade` VALUES ('20', '1', '2018-01-17 00:00:00'); 111 | INSERT INTO `trade` VALUES ('21', '1', '2018-01-17 00:00:00'); 112 | INSERT INTO `trade` VALUES ('22', '1', '2018-01-17 00:00:00'); 113 | INSERT INTO `trade` VALUES ('23', '1', '2018-01-17 00:00:00'); 114 | INSERT INTO `trade` VALUES ('24', '1', '2018-01-17 00:00:00'); 115 | INSERT INTO `trade` VALUES ('25', '1', '2018-01-17 00:00:00'); 116 | INSERT INTO `trade` VALUES ('26', '2', '2018-01-19 00:00:00'); 117 | INSERT INTO `trade` VALUES ('27', '2', '2018-01-19 00:00:00'); 118 | INSERT INTO `trade` VALUES ('28', '2', '2018-01-19 00:00:00'); 119 | INSERT INTO `trade` VALUES ('29', '2', '2018-01-19 00:00:00'); 120 | INSERT INTO `trade` VALUES ('30', '2', '2018-01-19 00:00:00'); 121 | INSERT INTO `trade` VALUES ('31', '2', '2018-01-19 00:00:00'); 122 | 123 | -- ---------------------------- 124 | -- Table structure for tradeitem 125 | -- ---------------------------- 126 | DROP TABLE IF EXISTS `tradeitem`; 127 | CREATE TABLE `tradeitem` ( 128 | `itemid` int(11) NOT NULL AUTO_INCREMENT, 129 | `computerid` int(11) DEFAULT NULL, 130 | `quantity` int(11) DEFAULT NULL, 131 | `tradeid` int(11) DEFAULT NULL, 132 | PRIMARY KEY (`itemid`), 133 | KEY `book_id_fk` (`computerid`), 134 | KEY `trade_id_fk` (`tradeid`), 135 | CONSTRAINT `tradeitem_ibfk_1` FOREIGN KEY (`computerid`) REFERENCES `mycomputers` (`Id`), 136 | CONSTRAINT `tradeitem_ibfk_2` FOREIGN KEY (`tradeid`) REFERENCES `trade` (`tradeid`) 137 | ) ENGINE=InnoDB AUTO_INCREMENT=61 DEFAULT CHARSET=gb2312; 138 | 139 | -- ---------------------------- 140 | -- Records of tradeitem 141 | -- ---------------------------- 142 | INSERT INTO `tradeitem` VALUES ('22', '19', '10', '12'); 143 | INSERT INTO `tradeitem` VALUES ('23', '27', '10', '12'); 144 | INSERT INTO `tradeitem` VALUES ('24', '7', '10', '12'); 145 | INSERT INTO `tradeitem` VALUES ('25', '1', '1', '13'); 146 | INSERT INTO `tradeitem` VALUES ('26', '13', '2', '13'); 147 | INSERT INTO `tradeitem` VALUES ('27', '14', '3', '13'); 148 | INSERT INTO `tradeitem` VALUES ('28', '15', '4', '13'); 149 | INSERT INTO `tradeitem` VALUES ('29', '1', '1', '14'); 150 | INSERT INTO `tradeitem` VALUES ('30', '13', '2', '14'); 151 | INSERT INTO `tradeitem` VALUES ('31', '14', '3', '14'); 152 | INSERT INTO `tradeitem` VALUES ('32', '15', '4', '14'); 153 | INSERT INTO `tradeitem` VALUES ('33', '22', '5', '14'); 154 | INSERT INTO `tradeitem` VALUES ('34', '23', '5', '14'); 155 | INSERT INTO `tradeitem` VALUES ('35', '24', '5', '14'); 156 | INSERT INTO `tradeitem` VALUES ('36', '2', '1', '15'); 157 | INSERT INTO `tradeitem` VALUES ('37', '1', '2', '15'); 158 | INSERT INTO `tradeitem` VALUES ('38', '3', '1', '15'); 159 | INSERT INTO `tradeitem` VALUES ('39', '2', '1', '16'); 160 | INSERT INTO `tradeitem` VALUES ('40', '1', '3', '16'); 161 | INSERT INTO `tradeitem` VALUES ('41', '3', '1', '16'); 162 | INSERT INTO `tradeitem` VALUES ('47', '1', '1', '19'); 163 | INSERT INTO `tradeitem` VALUES ('48', '2', '1', '19'); 164 | INSERT INTO `tradeitem` VALUES ('49', '3', '1', '19'); 165 | INSERT INTO `tradeitem` VALUES ('50', '1', '1', '27'); 166 | INSERT INTO `tradeitem` VALUES ('51', '6', '1', '27'); 167 | INSERT INTO `tradeitem` VALUES ('52', '2', '1', '28'); 168 | INSERT INTO `tradeitem` VALUES ('53', '6', '1', '29'); 169 | INSERT INTO `tradeitem` VALUES ('54', '2', '1', '30'); 170 | INSERT INTO `tradeitem` VALUES ('55', '20', '1', '31'); 171 | INSERT INTO `tradeitem` VALUES ('56', '11', '1', '31'); 172 | 173 | -- ---------------------------- 174 | -- Table structure for userinfo 175 | -- ---------------------------- 176 | DROP TABLE IF EXISTS `userinfo`; 177 | CREATE TABLE `userinfo` ( 178 | `userid` int(11) NOT NULL AUTO_INCREMENT, 179 | `username` varchar(50) DEFAULT NULL, 180 | `accountid` int(11) DEFAULT NULL, 181 | PRIMARY KEY (`userid`), 182 | KEY `account_id_fk` (`accountid`), 183 | CONSTRAINT `userinfo_ibfk_1` FOREIGN KEY (`accountid`) REFERENCES `account` (`accountid`) 184 | ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=gb2312; 185 | 186 | -- ---------------------------- 187 | -- Records of userinfo 188 | -- ---------------------------- 189 | INSERT INTO `userinfo` VALUES ('1', 'Tom', '1'); 190 | INSERT INTO `userinfo` VALUES ('2', 'AAA', '1'); 191 | INSERT INTO `userinfo` VALUES ('3', 'BB', '1'); 192 | INSERT INTO `userinfo` VALUES ('4', 'CC', '1'); 193 | INSERT INTO `userinfo` VALUES ('5', 'DD', '1'); 194 | INSERT INTO `userinfo` VALUES ('6', 'EE', '1'); 195 | SET FOREIGN_KEY_CHECKS=1; 196 | -------------------------------------------------------------------------------- /src/c3p0-config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | root 8 | root 9 | jdbc:mysql:///estore 10 | com.mysql.jdbc.Driver 11 | 12 | 2 13 | 5 14 | 5 15 | 10 16 | 17 | 20 18 | 5 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/com/xmut/estore/dao/AccountDAO.java: -------------------------------------------------------------------------------- 1 | package com.xmut.estore.dao; 2 | 3 | import com.xmut.estore.domain.Account; 4 | 5 | public interface AccountDAO { 6 | 7 | /** 8 | * 根据 accountId 获取对应的 Account 对象 9 | * @param accountId 10 | * @return 11 | */ 12 | public abstract Account get(Integer accountId); 13 | 14 | /** 15 | * 根据传入的 accountId, amount 更新指定账户的余额: 扣除 amount 指定的钱数 16 | * @param accountId 17 | * @param amount 18 | */ 19 | public abstract void updateBalance(Integer accountId, float amount); 20 | 21 | } -------------------------------------------------------------------------------- /src/com/xmut/estore/dao/ComputerDAO.java: -------------------------------------------------------------------------------- 1 | package com.xmut.estore.dao; 2 | 3 | import java.util.Collection; 4 | import java.util.List; 5 | 6 | import com.xmut.estore.domain.Computer; 7 | import com.xmut.estore.domain.ShoppingCartItem; 8 | import com.xmut.estore.web.CriteriaComputer; 9 | import com.xmut.estore.web.Page; 10 | 11 | 12 | 13 | public interface ComputerDAO { 14 | 15 | /** 16 | * 根据 id 获取指定 Computer 对象 17 | * @param id 18 | * @return 19 | */ 20 | public abstract Computer getComputer(int id); 21 | 22 | /** 23 | * 根据传入的 CriteriaComputer 对象返回对应的 Page 对象 24 | * @param cc 25 | * @return 26 | */ 27 | public abstract Page getPage(CriteriaComputer cc); 28 | 29 | /** 30 | * 根据传入的 CriteriaComputer 对象返回其对应的记录数 31 | * @param cc 32 | * @return 33 | */ 34 | public abstract long getTotalComputerNumber(CriteriaComputer cc); 35 | 36 | /** 37 | * 根据传入的 CriteriaComputer 和 pageSize 返回当前页对应的 List 38 | * @param cc 39 | * @param pageNo 40 | * @param pageSize 41 | * @return 42 | */ 43 | public abstract List getPageList(CriteriaComputer cc,int pageSize); 44 | 45 | /** 46 | * 返回指定 id 的 book 的 storeNumber 字段的值 47 | * @param id 48 | * @return 49 | */ 50 | public abstract int getStoreNumber(Integer id); 51 | 52 | /** 53 | * 根据传入的 ShoppingCartItem 的集合, 54 | * 批量更新computers 数据表的 storenumber 和 salesnumber 字段的值 55 | * @param items 56 | */ 57 | public abstract void batchUpdateStoreNumberAndSalesAmount( 58 | Collection items); 59 | /** 60 | * 61 | * 获取数据库的Computer图片的URL 62 | */ 63 | public abstract String getComputerImgUrl(int id); 64 | 65 | 66 | 67 | } -------------------------------------------------------------------------------- /src/com/xmut/estore/dao/Dao.java: -------------------------------------------------------------------------------- 1 | package com.xmut.estore.dao; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * Dao 接口, 定义 Dao 的基本操作, 由 BaseDao 提供实现. 7 | * @param : Dao 实际操作的泛型类型 8 | */ 9 | public interface Dao { 10 | 11 | /** 12 | * 执行 INSERT 操作, 返回插入后的记录的 ID 13 | * @param sql: 待执行的 SQL 语句 14 | * @param args: 填充占位符的可变参数 15 | * @return: 插入新记录的 id 16 | */ 17 | long insert(String sql, Object ... args); 18 | 19 | /** 20 | * 执行 UPDATE 操作, 包括 INSERT(但没有返回值), UPDATE, DELETE 21 | * @param sql: 待执行的 SQL 语句 22 | * @param args: 填充占位符的可变参数 23 | */ 24 | void update(String sql, Object ... args); 25 | 26 | /** 27 | * 执行单条记录的查询操作, 返回与记录对应的类的一个对象 28 | * @param sql: 待执行的 SQL 语句 29 | * @param args: 填充占位符的可变参数 30 | * @return: 与记录对应的类的一个对象 31 | */ 32 | T query(String sql, Object ... args); 33 | 34 | /** 35 | * 执行多条记录的查询操作, 返回与记录对应的类的一个 List 36 | * @param sql: 待执行的 SQL 语句 37 | * @param args: 填充占位符的可变参数 38 | * @return: 与记录对应的类的一个 List 39 | */ 40 | List queryForList(String sql, Object ... args); 41 | 42 | /** 43 | * 执行一个属性或值的查询操作, 例如查询某一条记录的一个字段, 或查询某个统计信息, 返回要查询的值 44 | * @param sql: 待执行的 SQL 语句 45 | * @param args: 填充占位符的可变参数 46 | * @return: 执行一个属性或值的查询操作, 例如查询某一条记录的一个字段, 或查询某个统计信息, 返回要查询的值 47 | */ 48 | V getSingleVal(String sql, Object ... args); 49 | 50 | /** 51 | * 执行批量更新操作 52 | * @param sql: 待执行的 SQL 语句 53 | * @param args: 填充占位符的可变参数 54 | */ 55 | void batch(String sql, Object[]... params); 56 | } -------------------------------------------------------------------------------- /src/com/xmut/estore/dao/TradeDAO.java: -------------------------------------------------------------------------------- 1 | package com.xmut.estore.dao; 2 | 3 | import java.util.Set; 4 | 5 | import com.xmut.estore.domain.Trade; 6 | 7 | 8 | 9 | public interface TradeDAO { 10 | 11 | /** 12 | * 向数据表中插入 Trade 对象 13 | * @param trade 14 | */ 15 | public abstract void insert(Trade trade); 16 | 17 | /** 18 | * 根据 userId 获取和其关联的 Trade 的集合 19 | * @param userId 20 | * @return 21 | */ 22 | public abstract Set getTradesWithUserId(Integer userId); 23 | 24 | } -------------------------------------------------------------------------------- /src/com/xmut/estore/dao/TradeItemDAO.java: -------------------------------------------------------------------------------- 1 | package com.xmut.estore.dao; 2 | 3 | import java.util.Collection; 4 | import java.util.Set; 5 | 6 | import com.xmut.estore.domain.TradeItem; 7 | 8 | 9 | 10 | public interface TradeItemDAO { 11 | 12 | /** 13 | * 批量保存 TradeItem 对象 14 | * @param items 15 | */ 16 | public abstract void batchSave(Collection items); 17 | 18 | /** 19 | * 根据 tradeId 获取和其关联的 TradeItem 的集合 20 | * @param tradeId 21 | * @return 22 | */ 23 | public abstract Set getTradeItemsWithTradeId(Integer tradeId); 24 | 25 | } 26 | 27 | -------------------------------------------------------------------------------- /src/com/xmut/estore/dao/UserDAO.java: -------------------------------------------------------------------------------- 1 | package com.xmut.estore.dao; 2 | 3 | import com.xmut.estore.domain.User; 4 | 5 | public interface UserDAO { 6 | 7 | /** 8 | * 根据用户名获取 User 对象 9 | * @param username 10 | * @return 11 | */ 12 | public abstract User getUser(String username); 13 | 14 | } 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/com/xmut/estore/dao/impl/AccountDAOIml.java: -------------------------------------------------------------------------------- 1 | package com.xmut.estore.dao.impl; 2 | 3 | import com.xmut.estore.dao.AccountDAO; 4 | import com.xmut.estore.domain.Account; 5 | 6 | public class AccountDAOIml extends BaseDAO implements AccountDAO { 7 | 8 | @Override 9 | public Account get(Integer accountId) { 10 | String sql = "SELECT accountId, balance FROM account WHERE accountId = ?"; 11 | return query(sql, accountId); 12 | } 13 | 14 | @Override 15 | public void updateBalance(Integer accountId, float amount) { 16 | String sql = "UPDATE account SET balance = balance - ? WHERE accountId = ?"; 17 | update(sql, amount, accountId); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/com/xmut/estore/dao/impl/BaseDAO.java: -------------------------------------------------------------------------------- 1 | package com.xmut.estore.dao.impl; 2 | 3 | import java.sql.Connection; 4 | import java.sql.PreparedStatement; 5 | import java.sql.ResultSet; 6 | import java.sql.Statement; 7 | import java.util.List; 8 | 9 | import org.apache.commons.dbutils.QueryRunner; 10 | import org.apache.commons.dbutils.handlers.BeanHandler; 11 | import org.apache.commons.dbutils.handlers.BeanListHandler; 12 | import org.apache.commons.dbutils.handlers.ScalarHandler; 13 | 14 | import com.xmut.estore.dao.Dao; 15 | import com.xmut.estore.db.JDBCUtils; 16 | import com.xmut.estore.utils.ReflectionUtils; 17 | import com.xmut.estore.web.ConnectionContext; 18 | 19 | public class BaseDAO implements Dao { 20 | 21 | private QueryRunner queryRunner = new QueryRunner(); 22 | 23 | private Class clazz; 24 | 25 | public BaseDAO() { 26 | clazz = ReflectionUtils.getSuperGenericType(getClass()); 27 | } 28 | 29 | @Override 30 | public long insert(String sql, Object... args) { 31 | 32 | long id = 0; 33 | 34 | Connection connection = null; 35 | PreparedStatement preparedStatement = null; 36 | ResultSet resultSet = null; 37 | //获取ID 38 | try { 39 | connection = ConnectionContext.getInstance().get(); 40 | // connection = JDBCUtils.getConnection(); 41 | preparedStatement = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS); 42 | 43 | if(args != null){ 44 | for(int i = 0; i < args.length; i++){ 45 | preparedStatement.setObject(i + 1, args[i]); 46 | } 47 | } 48 | 49 | preparedStatement.executeUpdate(); 50 | 51 | //获取生成的主键值 52 | resultSet = preparedStatement.getGeneratedKeys(); 53 | if(resultSet.next()){ 54 | id = resultSet.getLong(1); 55 | } 56 | 57 | } catch (Exception e) { 58 | e.printStackTrace(); 59 | } finally{ 60 | JDBCUtils.release(resultSet, preparedStatement); 61 | } 62 | 63 | return id; 64 | } 65 | 66 | @Override 67 | public void update(String sql, Object... args) { 68 | Connection connection = null; 69 | 70 | try { 71 | // connection = ConnectionContext.getInstance().get(); 72 | connection = JDBCUtils.getConnection(); 73 | queryRunner.update(connection, sql, args); 74 | } catch (Exception e) { 75 | e.printStackTrace(); 76 | }finally{ 77 | JDBCUtils.release(connection); 78 | } 79 | } 80 | 81 | @Override 82 | public T query(String sql, Object... args) { 83 | 84 | Connection connection = null; 85 | 86 | try { 87 | // connection = ConnectionContext.getInstance().get(); 88 | connection = JDBCUtils.getConnection(); 89 | return queryRunner.query(connection, sql, new BeanHandler<>(clazz), args); 90 | } catch (Exception e) { 91 | e.printStackTrace(); 92 | }finally{ 93 | JDBCUtils.release(connection); 94 | } 95 | 96 | return null; 97 | } 98 | 99 | @Override 100 | public List queryForList(String sql, Object... args) { 101 | Connection connection = null; 102 | 103 | try { 104 | // connection = ConnectionContext.getInstance().get(); 105 | connection = JDBCUtils.getConnection(); 106 | return queryRunner.query(connection, sql, new BeanListHandler<>(clazz), args); 107 | } catch (Exception e) { 108 | e.printStackTrace(); 109 | } finally{ 110 | JDBCUtils.release(connection); 111 | } 112 | return null; 113 | } 114 | 115 | @Override 116 | public V getSingleVal(String sql, Object... args) { 117 | Connection connection = null; 118 | 119 | try { 120 | // connection = ConnectionContext.getInstance().get(); 121 | connection = JDBCUtils.getConnection(); 122 | return (V)queryRunner.query(connection, sql, new ScalarHandler(), args); 123 | } catch (Exception e) { 124 | e.printStackTrace(); 125 | } finally{ 126 | JDBCUtils.release(connection); 127 | } 128 | 129 | return null; 130 | } 131 | 132 | @Override 133 | public void batch(String sql, Object[]... params) { 134 | Connection connection = null; 135 | 136 | try { 137 | // connection = ConnectionContext.getInstance().get(); 138 | connection = JDBCUtils.getConnection(); 139 | queryRunner.batch(connection, sql, params); 140 | } catch (Exception e) { 141 | e.printStackTrace(); 142 | } finally{ 143 | JDBCUtils.release(connection); 144 | } 145 | 146 | } 147 | 148 | } 149 | -------------------------------------------------------------------------------- /src/com/xmut/estore/dao/impl/ComputerDAOImpl.java: -------------------------------------------------------------------------------- 1 | package com.xmut.estore.dao.impl; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collection; 5 | import java.util.List; 6 | 7 | import com.xmut.estore.dao.ComputerDAO; 8 | import com.xmut.estore.domain.Computer; 9 | import com.xmut.estore.domain.ShoppingCartItem; 10 | import com.xmut.estore.web.CriteriaComputer; 11 | import com.xmut.estore.web.Page; 12 | 13 | public class ComputerDAOImpl extends BaseDAO implements ComputerDAO{ 14 | 15 | @Override 16 | public Computer getComputer(int id) { 17 | // TODO Auto-generated method stub 18 | String sql = "SELECT id,brand,model,price,publishingDate,"+ 19 | "salesAmount,storeNumber,Remark,Url FROM mycomputers WHERE id = ?"; 20 | 21 | return query(sql, id); 22 | } 23 | //3. 24 | //将请求条件封装成CriteriaComputer 25 | @Override 26 | public Page getPage(CriteriaComputer cc) { 27 | // TODO Auto-generated method stub 28 | Page page = new Page<>(cc.getPageNo()); 29 | 30 | page.setTotalItemNumber(getTotalComputerNumber(cc)); 31 | //校验pageNo的合法性 32 | cc.setPageNo(page.getPageNo()); 33 | page.setList(getPageList(cc, 6)); 34 | return page; 35 | } 36 | //1. 37 | @Override 38 | public long getTotalComputerNumber(CriteriaComputer cc) { 39 | // TODO Auto-generated method stub 40 | String sql = "SELECT count(id) FROM mycomputers WHERE price BETWEEN ? AND ?"; 41 | return getSingleVal(sql, cc.getMinPrice(), cc.getMaxPrice()); 42 | } 43 | /** 44 | * 分页逻辑,用LIMIT,从0开始 45 | * 46 | */ 47 | //2. 48 | @Override 49 | public List getPageList(CriteriaComputer cc, int pageSize) { 50 | // TODO Auto-generated method stub 51 | String sql = "SELECT id,brand,model,price,publishingDate,"+ 52 | "salesAmount,storeNumber,Remark,Url FROM mycomputers WHERE price BETWEEN ? AND ?"+ 53 | "LIMIT ?,?"; 54 | 55 | return queryForList(sql, cc.getMinPrice(),cc.getMaxPrice(),(cc.getPageNo() - 1)*pageSize,pageSize); 56 | } 57 | 58 | @Override 59 | public int getStoreNumber(Integer id) { 60 | // TODO Auto-generated method stub 61 | String sql = "SELECT storeNumber FROM mycomputers WHERE id = ?"; 62 | return getSingleVal(sql, id); 63 | } 64 | 65 | @Override 66 | public void batchUpdateStoreNumberAndSalesAmount(Collection items) { 67 | // TODO Auto-generated method stub 68 | String sql = "UPDATE mycomputers SET salesAmount = salesAmount + ?, " + 69 | "storeNumber = storeNumber - ? " + 70 | "WHERE id = ?"; 71 | Object [][] params = null; 72 | params = new Object[items.size()][3]; 73 | List scis = new ArrayList<>(items); 74 | for(int i = 0; i < items.size(); i++){ 75 | params[i][0] = scis.get(i).getQuantity(); 76 | params[i][1] = scis.get(i).getQuantity(); 77 | params[i][2] = scis.get(i).getComputer().getId(); 78 | } 79 | batch(sql, params); 80 | } 81 | @Override 82 | public String getComputerImgUrl(int id) { 83 | // TODO Auto-generated method stub 84 | String sql = "SELECT url FROM mycomputers WHERE id=?"; 85 | return getSingleVal(sql, id); 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /src/com/xmut/estore/dao/impl/TradeDAOImpl.java: -------------------------------------------------------------------------------- 1 | package com.xmut.estore.dao.impl; 2 | 3 | import java.util.LinkedHashSet; 4 | import java.util.Set; 5 | 6 | import com.xmut.estore.dao.TradeDAO; 7 | import com.xmut.estore.domain.Trade; 8 | 9 | public class TradeDAOImpl extends BaseDAO implements TradeDAO { 10 | 11 | @Override 12 | public void insert(Trade trade) { 13 | String sql = "INSERT INTO trade (userid, tradetime) VALUES " + 14 | "(?, ?)"; 15 | long tradeId = insert(sql, trade.getUserId(), trade.getTradeTime()); 16 | trade.setTradeId((int)tradeId); 17 | } 18 | 19 | @Override 20 | public Set getTradesWithUserId(Integer userId) { 21 | String sql = "SELECT tradeId, userId, tradeTime FROM trade " + 22 | "WHERE userId = ? ORDER BY tradeTime DESC"; 23 | return new LinkedHashSet(queryForList(sql, userId)); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/com/xmut/estore/dao/impl/TradeItemDAOImpl.java: -------------------------------------------------------------------------------- 1 | package com.xmut.estore.dao.impl; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collection; 5 | import java.util.HashSet; 6 | import java.util.List; 7 | import java.util.Set; 8 | 9 | import com.xmut.estore.dao.TradeItemDAO; 10 | import com.xmut.estore.domain.TradeItem; 11 | 12 | public class TradeItemDAOImpl extends BaseDAO implements TradeItemDAO { 13 | 14 | @Override 15 | public void batchSave(Collection items) { 16 | String sql = "INSERT INTO tradeitem(computerid, quantity, tradeid) " + 17 | "VALUES(?,?,?)"; 18 | Object [][] params = new Object[items.size()][3]; 19 | 20 | List tradeItems = new ArrayList<>(items); 21 | for(int i = 0; i < tradeItems.size(); i++){ 22 | params[i][0] = tradeItems.get(i).getComputerId(); 23 | params[i][1] = tradeItems.get(i).getQuantity(); 24 | params[i][2] = tradeItems.get(i).getTradeId(); 25 | } 26 | 27 | batch(sql, params); 28 | } 29 | 30 | @Override 31 | public Set getTradeItemsWithTradeId(Integer tradeId) { 32 | String sql = "SELECT itemId tradeItemId, computerId, " + 33 | "quantity, tradeId FROM tradeitem WHERE tradeid = ?"; 34 | return new HashSet<>(queryForList(sql, tradeId)); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/com/xmut/estore/dao/impl/UserDAOImpl.java: -------------------------------------------------------------------------------- 1 | package com.xmut.estore.dao.impl; 2 | 3 | import com.xmut.estore.dao.UserDAO; 4 | import com.xmut.estore.domain.User; 5 | 6 | public class UserDAOImpl extends BaseDAO implements UserDAO { 7 | 8 | @Override 9 | public User getUser(String username) { 10 | String sql = "SELECT userId, username, accountId " + 11 | "FROM userinfo WHERE username = ?"; 12 | return query(sql, username); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/com/xmut/estore/db/JDBCUtils.java: -------------------------------------------------------------------------------- 1 | package com.xmut.estore.db; 2 | 3 | import java.sql.Connection; 4 | import java.sql.ResultSet; 5 | import java.sql.SQLException; 6 | import java.sql.Statement; 7 | 8 | import javax.sql.DataSource; 9 | 10 | import com.xmut.estore.exception.DBException; 11 | import com.mchange.v2.c3p0.ComboPooledDataSource; 12 | 13 | /** 14 | * 15 | * JDBC 的工具类 16 | * 17 | */ 18 | public class JDBCUtils { 19 | 20 | private static DataSource dataSource = null; 21 | 22 | static{ 23 | dataSource = new ComboPooledDataSource("javawebapp"); 24 | } 25 | 26 | //获取数据库连接 27 | public static Connection getConnection(){ 28 | try { 29 | return dataSource.getConnection(); 30 | } catch (SQLException e) { 31 | e.printStackTrace(); 32 | throw new DBException("数据库连接错误!"); 33 | } 34 | } 35 | 36 | //关闭数据库连接 37 | public static void release(Connection connection) { 38 | try { 39 | if(connection != null){ 40 | connection.close(); 41 | } 42 | } catch (SQLException e) { 43 | e.printStackTrace(); 44 | throw new DBException("数据库连接错误!"); 45 | } 46 | } 47 | 48 | //关闭数据库连接 49 | public static void release(ResultSet rs, Statement statement) { 50 | try { 51 | if(rs != null){ 52 | rs.close(); 53 | } 54 | } catch (SQLException e) { 55 | e.printStackTrace(); 56 | throw new DBException("数据库连接错误!"); 57 | } 58 | 59 | try { 60 | if(statement != null){ 61 | statement.close(); 62 | } 63 | } catch (SQLException e) { 64 | e.printStackTrace(); 65 | throw new DBException("数据库连接错误!"); 66 | } 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /src/com/xmut/estore/domain/Account.java: -------------------------------------------------------------------------------- 1 | package com.xmut.estore.domain; 2 | 3 | public class Account { 4 | 5 | private Integer accountId; 6 | private int balance; 7 | 8 | public Integer getAccountId() { 9 | return accountId; 10 | } 11 | 12 | public void setAccountId(Integer accountId) { 13 | this.accountId = accountId; 14 | } 15 | 16 | public int getBalance() { 17 | return balance; 18 | } 19 | 20 | public void setBalance(int balance) { 21 | this.balance = balance; 22 | } 23 | 24 | public Account(Integer accountId, int balance) { 25 | super(); 26 | this.accountId = accountId; 27 | this.balance = balance; 28 | } 29 | 30 | @Override 31 | public String toString() { 32 | return "Account [accountId=" + accountId + ", balance=" + balance + "]"; 33 | } 34 | 35 | public Account() { 36 | // TODO Auto-generated constructor stub 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/com/xmut/estore/domain/Computer.java: -------------------------------------------------------------------------------- 1 | package com.xmut.estore.domain; 2 | 3 | import java.sql.Date; 4 | 5 | public class Computer { 6 | private Integer id; 7 | 8 | private String brand; 9 | 10 | private String model; 11 | 12 | private float price; 13 | 14 | private Date publishingDate; 15 | 16 | private int salesAmount; 17 | 18 | private int storeNumber; 19 | 20 | private String remark; 21 | 22 | private String url; 23 | 24 | public Integer getId() { 25 | return id; 26 | } 27 | public void setId(Integer id) { 28 | this.id = id; 29 | } 30 | public String getBrand() { 31 | return brand; 32 | } 33 | public void setBrand(String brand) { 34 | this.brand = brand; 35 | } 36 | public String getModel() { 37 | return model; 38 | } 39 | public void setModel(String model) { 40 | this.model = model; 41 | } 42 | public float getPrice() { 43 | return price; 44 | } 45 | public void setPrice(float price) { 46 | this.price = price; 47 | } 48 | public Date getPublishingDate() { 49 | return publishingDate; 50 | } 51 | public void setPublishingDate(Date publishingDate) { 52 | this.publishingDate = publishingDate; 53 | } 54 | public int getSalesAmount() { 55 | return salesAmount; 56 | } 57 | public void setSalesAmount(int salesAmount) { 58 | this.salesAmount = salesAmount; 59 | } 60 | public int getStoreNumber() { 61 | return storeNumber; 62 | } 63 | public void setStoreNumber(int storeNumber) { 64 | this.storeNumber = storeNumber; 65 | } 66 | public String getRemark() { 67 | return remark; 68 | } 69 | public void setRemark(String remark) { 70 | this.remark = remark; 71 | } 72 | public String getUrl() { 73 | return url; 74 | } 75 | public void setUrl(String url) { 76 | this.url = url; 77 | } 78 | @Override 79 | public String toString() { 80 | return "Computer [id=" + id + ", brand=" + brand + ", model=" + model + ", price=" + price + ", publishingDate=" 81 | + publishingDate + ", salesAmount=" + salesAmount + ", storeNumber=" + storeNumber + ", remark=" 82 | + remark + ", url=" + url + "]"+"/n"; 83 | } 84 | 85 | 86 | 87 | } 88 | -------------------------------------------------------------------------------- /src/com/xmut/estore/domain/ShoppingCart.java: -------------------------------------------------------------------------------- 1 | package com.xmut.estore.domain; 2 | 3 | import java.util.Collection; 4 | import java.util.HashMap; 5 | import java.util.Map; 6 | 7 | import com.xmut.estore.domain.Computer; 8 | import com.xmut.estore.domain.ShoppingCartItem; 9 | 10 | public class ShoppingCart { 11 | 12 | private Map computers = new HashMap<>(); 13 | 14 | /** 15 | * 修改指定购物项的数量 16 | */ 17 | public void updateItemQuantity(Integer id, int quantity){ 18 | ShoppingCartItem sci =computers.get(id); 19 | if(sci != null){ 20 | sci.setQuantity(quantity); 21 | } 22 | } 23 | 24 | /** 25 | * 移除指定的购物项 26 | * @param id 27 | */ 28 | public void removeItem(Integer id){ 29 | computers.remove(id); 30 | } 31 | 32 | /** 33 | * 清空购物车 34 | */ 35 | public void clear(){ 36 | computers.clear(); 37 | } 38 | 39 | /** 40 | * 返回购物车是否为空 41 | * @return 42 | */ 43 | public boolean isEmpty(){ 44 | return computers.isEmpty(); 45 | } 46 | 47 | /** 48 | * 获取购物车中所有的商品的总的钱数 49 | * @return 50 | */ 51 | public float getTotalMoney(){ 52 | float total = 0; 53 | 54 | for(ShoppingCartItem sci: getItems()){ 55 | total += sci.getItemMoney(); 56 | } 57 | 58 | return total; 59 | } 60 | 61 | /** 62 | * 获取购物车中的所有的 ShoppingCartItem 组成的集合 63 | * @return 64 | */ 65 | public Collection getItems(){ 66 | return computers.values(); 67 | } 68 | 69 | /** 70 | * 返回购物车中商品的总数量 71 | * @return 72 | */ 73 | public int getComputerNumber(){ 74 | int total = 0; 75 | 76 | for(ShoppingCartItem sci: computers.values()){ 77 | total += sci.getQuantity(); 78 | } 79 | 80 | return total; 81 | } 82 | 83 | public Map getComputers() { 84 | return computers; 85 | } 86 | 87 | /** 88 | * 检验购物车中是否有 id 指定的商品 89 | * @param id 90 | * @return 91 | */ 92 | public boolean hasComputer(Integer id){ 93 | return computers.containsKey(id); 94 | } 95 | 96 | /** 97 | * 向购物车中添加一件商品 98 | * @param computer 99 | */ 100 | public void addComputer(Computer computer){ 101 | //1. 检查购物车中有没有该商品, 若有, 则使其数量 +1, 若没有, 102 | //新创建其对应的 ShoppingCartItem, 并把其加入到 computers 中 103 | ShoppingCartItem sci = computers.get(computer.getId()); 104 | 105 | if(sci == null){ 106 | sci = new ShoppingCartItem(computer); 107 | computers.put(computer.getId(), sci); 108 | }else{ 109 | sci.increment(); 110 | } 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/com/xmut/estore/domain/ShoppingCartItem.java: -------------------------------------------------------------------------------- 1 | package com.xmut.estore.domain; 2 | 3 | import com.xmut.estore.domain.Computer; 4 | 5 | /** 6 | * 封装了购物车中的商品, 包含对商品的引用以及购物车中该商品的数量 7 | * 8 | */ 9 | public class ShoppingCartItem { 10 | 11 | private Computer computer; 12 | private int quantity; 13 | 14 | public ShoppingCartItem(Computer computer) { 15 | this.computer = computer; 16 | this.quantity = 1; 17 | } 18 | 19 | public Computer getComputer() { 20 | return computer; 21 | } 22 | 23 | public int getQuantity() { 24 | return quantity; 25 | } 26 | 27 | public void setQuantity(int quantity) { 28 | this.quantity = quantity; 29 | } 30 | 31 | /** 32 | * 返回该商品在购物车中的钱数 33 | * @return 34 | */ 35 | public float getItemMoney(){ 36 | return computer.getPrice() * quantity; 37 | } 38 | 39 | /** 40 | * 使商品数量 + 1 41 | */ 42 | public void increment(){ 43 | quantity++; 44 | } 45 | 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/com/xmut/estore/domain/Trade.java: -------------------------------------------------------------------------------- 1 | package com.xmut.estore.domain; 2 | 3 | import java.sql.Date; 4 | import java.util.LinkedHashSet; 5 | import java.util.Set; 6 | 7 | import com.xmut.estore.domain.TradeItem; 8 | 9 | public class Trade { 10 | 11 | //Trade 对象对应的 id 12 | private Integer tradeId; 13 | 14 | //交易的时间 15 | private Date tradeTime; 16 | 17 | //Trade 关联的多个 TradeItem 18 | private Set items = new LinkedHashSet(); 19 | 20 | public void setItems(Set items) { 21 | this.items = items; 22 | } 23 | 24 | public Set getItems() { 25 | return items; 26 | } 27 | 28 | //和 Trade 关联的 User 的 userId 29 | private Integer userId; 30 | 31 | public Integer getTradeId() { 32 | return tradeId; 33 | } 34 | 35 | public void setTradeId(Integer tradeId) { 36 | this.tradeId = tradeId; 37 | } 38 | 39 | public Integer getUserId() { 40 | return userId; 41 | } 42 | 43 | public void setUserId(Integer userId) { 44 | this.userId = userId; 45 | } 46 | 47 | public Date getTradeTime() { 48 | return tradeTime; 49 | } 50 | 51 | public void setTradeTime(Date tradeTime) { 52 | this.tradeTime = tradeTime; 53 | } 54 | 55 | @Override 56 | public String toString() { 57 | return "Trade [tradeId=" + tradeId + ", tradeTime=" + tradeTime 58 | + ", userId=" + userId + "]"; 59 | } 60 | } 61 | 62 | -------------------------------------------------------------------------------- /src/com/xmut/estore/domain/TradeItem.java: -------------------------------------------------------------------------------- 1 | package com.xmut.estore.domain; 2 | 3 | import com.xmut.estore.domain.Computer; 4 | 5 | public class TradeItem { 6 | 7 | private Integer tradeItemId; 8 | 9 | //和 TradeItem 关联的 Computer 10 | private Computer computer; 11 | 12 | private int quantity; 13 | 14 | //和 TradeItem 关联的 Computer 的 computerId 15 | private Integer computerId; 16 | 17 | private Integer tradeId; 18 | 19 | public void setComputer(Computer computer) { 20 | this.computer = computer; 21 | } 22 | 23 | public Computer getComputer() { 24 | return computer; 25 | } 26 | 27 | public Integer getTradeItemId() { 28 | return tradeItemId; 29 | } 30 | 31 | public void setTradeItemId(Integer tradeItemId) { 32 | this.tradeItemId = tradeItemId; 33 | } 34 | 35 | public Integer getComputerId() { 36 | return computerId; 37 | } 38 | 39 | public void setComputerId(Integer computerId) { 40 | this.computerId = computerId; 41 | } 42 | 43 | public int getQuantity() { 44 | return quantity; 45 | } 46 | 47 | public void setQuantity(int quantity) { 48 | this.quantity = quantity; 49 | } 50 | 51 | public Integer getTradeId() { 52 | return tradeId; 53 | } 54 | 55 | public void setTradeId(Integer tradeId) { 56 | this.tradeId = tradeId; 57 | } 58 | 59 | public TradeItem(Integer tradeItemId, Integer computerId, int quantity, 60 | Integer tradeId) { 61 | super(); 62 | this.tradeItemId = tradeItemId; 63 | this.computerId = computerId; 64 | this.quantity = quantity; 65 | this.tradeId = tradeId; 66 | } 67 | 68 | public TradeItem() { 69 | // TODO Auto-generated constructor stub 70 | } 71 | 72 | @Override 73 | public String toString() { 74 | return "TradeItem [tradeItemId=" + tradeItemId + ", quantity=" 75 | + quantity + ", computerId=" + computerId + "]"; 76 | } 77 | 78 | 79 | 80 | } 81 | -------------------------------------------------------------------------------- /src/com/xmut/estore/domain/User.java: -------------------------------------------------------------------------------- 1 | package com.xmut.estore.domain; 2 | 3 | import java.util.LinkedHashSet; 4 | import java.util.Set; 5 | 6 | public class User { 7 | 8 | private Integer userId; 9 | private String username; 10 | private int accountId; 11 | 12 | private Set trades = new LinkedHashSet(); 13 | 14 | public void setTrades(Set trades) { 15 | this.trades = trades; 16 | } 17 | 18 | public Set getTrades() { 19 | return trades; 20 | } 21 | 22 | public Integer getUserId() { 23 | return userId; 24 | } 25 | 26 | public void setUserId(Integer userId) { 27 | this.userId = userId; 28 | } 29 | 30 | public String getUsername() { 31 | return username; 32 | } 33 | 34 | public void setUsername(String username) { 35 | this.username = username; 36 | } 37 | 38 | public Integer getAccountId() { 39 | return accountId; 40 | } 41 | 42 | public void setAccountId(Integer accountId) { 43 | this.accountId = accountId; 44 | } 45 | 46 | @Override 47 | public String toString() { 48 | return "User [userId=" + userId + ", username=" + username 49 | + ", accountId=" + accountId + "]"; 50 | } 51 | 52 | public User(Integer userId, String username, int accountId) { 53 | super(); 54 | this.userId = userId; 55 | this.username = username; 56 | this.accountId = accountId; 57 | } 58 | 59 | public User() { 60 | // TODO Auto-generated constructor stub 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/com/xmut/estore/exception/DBException.java: -------------------------------------------------------------------------------- 1 | package com.xmut.estore.exception; 2 | 3 | public class DBException extends RuntimeException { 4 | /** 5 | * 6 | */ 7 | private static final long serialVersionUID = 1L; 8 | 9 | public DBException() { 10 | // TODO Auto-generated constructor stub 11 | } 12 | 13 | public DBException(String msg) { 14 | super(msg); 15 | } 16 | 17 | public DBException(String msg, Exception ex) { 18 | super(msg, ex); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/com/xmut/estore/filter/EncodingFilter.java: -------------------------------------------------------------------------------- 1 | package com.xmut.estore.filter; 2 | 3 | import java.io.IOException; 4 | import javax.servlet.Filter; 5 | import javax.servlet.FilterChain; 6 | import javax.servlet.FilterConfig; 7 | import javax.servlet.ServletException; 8 | import javax.servlet.ServletRequest; 9 | import javax.servlet.ServletResponse; 10 | 11 | /** 12 | * Servlet Filter implementation class EncodingFilter 13 | */ 14 | public class EncodingFilter implements Filter { 15 | 16 | /** 17 | * Default constructor. 18 | */ 19 | public EncodingFilter() { 20 | // TODO Auto-generated constructor stub 21 | } 22 | 23 | /** 24 | * @see Filter#destroy() 25 | */ 26 | public void destroy() { 27 | // TODO Auto-generated method stub 28 | } 29 | 30 | /** 31 | * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain) 32 | */ 33 | public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 34 | String encoding = filterConfig.getServletContext().getInitParameter("encoding"); 35 | request.setCharacterEncoding(encoding); 36 | chain.doFilter(request, response); 37 | } 38 | 39 | private FilterConfig filterConfig = null; 40 | 41 | public void init(FilterConfig fConfig) throws ServletException { 42 | this.filterConfig = fConfig; 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/com/xmut/estore/filter/TranactionFilter.java: -------------------------------------------------------------------------------- 1 | package com.xmut.estore.filter; 2 | 3 | import java.io.IOException; 4 | import java.sql.Connection; 5 | import java.sql.SQLException; 6 | 7 | import javax.servlet.Filter; 8 | import javax.servlet.FilterChain; 9 | import javax.servlet.FilterConfig; 10 | import javax.servlet.ServletException; 11 | import javax.servlet.ServletRequest; 12 | import javax.servlet.ServletResponse; 13 | import javax.servlet.http.HttpServletRequest; 14 | import javax.servlet.http.HttpServletResponse; 15 | 16 | import com.xmut.estore.db.JDBCUtils; 17 | import com.xmut.estore.web.ConnectionContext; 18 | 19 | /** 20 | * Servlet Filter implementation class TranactionFilter 21 | */ 22 | public class TranactionFilter implements Filter { 23 | 24 | /** 25 | * Default constructor. 26 | */ 27 | public TranactionFilter() { 28 | // TODO Auto-generated constructor stub 29 | } 30 | 31 | /** 32 | * @see Filter#destroy() 33 | */ 34 | public void destroy() { 35 | // TODO Auto-generated method stub 36 | } 37 | 38 | /** 39 | * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain) 40 | */ 41 | public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 42 | 43 | Connection connection = null; 44 | 45 | try { 46 | 47 | //1. 获取连接 48 | connection = JDBCUtils.getConnection(); 49 | 50 | //2. 开启事务 51 | connection.setAutoCommit(false); 52 | 53 | //3. 利用 ThreadLocal 把连接和当前线程绑定 54 | ConnectionContext.getInstance().bind(connection); 55 | 56 | //4. 把请求转给目标 Servlet 57 | chain.doFilter(request, response); 58 | 59 | //5. 提交事务 60 | connection.commit(); 61 | } catch (Exception e) { 62 | e.printStackTrace(); 63 | 64 | //6. 回滚事务 65 | try { 66 | connection.rollback(); 67 | } catch (SQLException e1) { 68 | e1.printStackTrace(); 69 | } 70 | 71 | HttpServletResponse resp = (HttpServletResponse) response; 72 | HttpServletRequest req = (HttpServletRequest) request; 73 | resp.sendRedirect(req.getContextPath() + "/error-1.jsp"); 74 | 75 | } finally{ 76 | //7. 解除绑定 77 | ConnectionContext.getInstance().remove(); 78 | 79 | //8. 关闭连接 80 | JDBCUtils.release(connection); 81 | 82 | } 83 | 84 | } 85 | 86 | /** 87 | * @see Filter#init(FilterConfig) 88 | */ 89 | public void init(FilterConfig fConfig) throws ServletException { 90 | // TODO Auto-generated method stub 91 | } 92 | 93 | } 94 | -------------------------------------------------------------------------------- /src/com/xmut/estore/service/AccountService.java: -------------------------------------------------------------------------------- 1 | package com.xmut.estore.service; 2 | 3 | import com.xmut.estore.dao.AccountDAO; 4 | import com.xmut.estore.dao.impl.AccountDAOIml; 5 | import com.xmut.estore.domain.Account; 6 | 7 | public class AccountService { 8 | 9 | private AccountDAO accountDAO = new AccountDAOIml(); 10 | 11 | public Account getAccount(int accountId){ 12 | return accountDAO.get(accountId); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/com/xmut/estore/service/ComputerService.java: -------------------------------------------------------------------------------- 1 | package com.xmut.estore.service; 2 | 3 | 4 | import java.sql.Date; 5 | import java.util.ArrayList; 6 | import java.util.Collection; 7 | 8 | 9 | import com.xmut.estore.dao.AccountDAO; 10 | import com.xmut.estore.dao.ComputerDAO; 11 | import com.xmut.estore.dao.TradeDAO; 12 | import com.xmut.estore.dao.TradeItemDAO; 13 | import com.xmut.estore.dao.UserDAO; 14 | import com.xmut.estore.dao.impl.AccountDAOIml; 15 | import com.xmut.estore.dao.impl.ComputerDAOImpl; 16 | import com.xmut.estore.dao.impl.TradeDAOImpl; 17 | import com.xmut.estore.dao.impl.TradeItemDAOImpl; 18 | import com.xmut.estore.dao.impl.UserDAOImpl; 19 | import com.xmut.estore.domain.Computer; 20 | import com.xmut.estore.domain.ShoppingCart; 21 | import com.xmut.estore.domain.ShoppingCartItem; 22 | import com.xmut.estore.domain.Trade; 23 | import com.xmut.estore.domain.TradeItem; 24 | import com.xmut.estore.web.CriteriaComputer; 25 | import com.xmut.estore.web.Page; 26 | 27 | public class ComputerService { 28 | private ComputerDAO computerDAO = new ComputerDAOImpl(); 29 | private AccountDAO accountDAO = new AccountDAOIml(); 30 | private TradeDAO tradeDAO = new TradeDAOImpl(); 31 | private UserDAO userDAO = new UserDAOImpl(); 32 | private TradeItemDAO tradeItemDAO = new TradeItemDAOImpl(); 33 | 34 | public Page getPage(CriteriaComputer cc){ 35 | return computerDAO.getPage(cc); 36 | } 37 | 38 | public Computer getComputer(int id) { 39 | // TODO Auto-generated method stub 40 | return computerDAO.getComputer(id); 41 | } 42 | 43 | public boolean addToCart(int id, ShoppingCart sc) { 44 | // TODO Auto-generated method stub 45 | Computer computer = computerDAO.getComputer(id); 46 | 47 | if (computer != null) { 48 | sc.addComputer(computer); 49 | return true; 50 | } 51 | return false; 52 | 53 | 54 | } 55 | //业务方法. 56 | public void cash(ShoppingCart shoppingCart, String username, 57 | String accountId) { 58 | 59 | //1. 更新 mycomputers 数据表相关记录的 salesamount 和 storenumber 60 | computerDAO.batchUpdateStoreNumberAndSalesAmount(shoppingCart.getItems()); 61 | 62 | int i = 10; 63 | 64 | //2. 更新 account 数据表的 balance 65 | accountDAO.updateBalance(Integer.parseInt(accountId), shoppingCart.getTotalMoney()); 66 | 67 | //3. 向 trade 数据表插入一条记录 68 | Trade trade = new Trade(); 69 | trade.setTradeTime(new Date(new java.util.Date().getTime())); 70 | trade.setUserId(userDAO.getUser(username).getUserId()); 71 | tradeDAO.insert(trade); 72 | 73 | //4. 向 tradeitem 数据表插入 n 条记录 74 | Collection items = new ArrayList<>(); 75 | for(ShoppingCartItem sci: shoppingCart.getItems()){ 76 | TradeItem tradeItem = new TradeItem(); 77 | 78 | tradeItem.setComputerId(sci.getComputer().getId()); 79 | tradeItem.setQuantity(sci.getQuantity()); 80 | tradeItem.setTradeId(trade.getTradeId()); 81 | 82 | items.add(tradeItem); 83 | } 84 | tradeItemDAO.batchSave(items); 85 | 86 | //5. 清空购物车 87 | shoppingCart.clear(); 88 | } 89 | 90 | 91 | 92 | public void updateItemQuantity(ShoppingCart sc, int id, int quantity) { 93 | sc.updateItemQuantity(id, quantity); 94 | } 95 | public void removeItemFromShoppingCart(ShoppingCart sc, int id) { 96 | sc.removeItem(id); 97 | } 98 | 99 | public void clearShoppingCart(ShoppingCart sc) { 100 | // TODO Auto-generated method stub 101 | sc.clear(); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /src/com/xmut/estore/service/UserService.java: -------------------------------------------------------------------------------- 1 | package com.xmut.estore.service; 2 | 3 | import java.util.Iterator; 4 | import java.util.Set; 5 | 6 | import com.xmut.estore.dao.ComputerDAO; 7 | import com.xmut.estore.dao.TradeDAO; 8 | import com.xmut.estore.dao.TradeItemDAO; 9 | import com.xmut.estore.dao.UserDAO; 10 | import com.xmut.estore.dao.impl.ComputerDAOImpl; 11 | import com.xmut.estore.dao.impl.TradeDAOImpl; 12 | import com.xmut.estore.dao.impl.TradeItemDAOImpl; 13 | import com.xmut.estore.dao.impl.UserDAOImpl; 14 | import com.xmut.estore.domain.Trade; 15 | import com.xmut.estore.domain.TradeItem; 16 | import com.xmut.estore.domain.User; 17 | 18 | public class UserService { 19 | 20 | private UserDAO userDAO = new UserDAOImpl(); 21 | 22 | public User getUserByUserName(String username){ 23 | return userDAO.getUser(username); 24 | } 25 | 26 | private TradeDAO tradeDAO = new TradeDAOImpl(); 27 | private TradeItemDAO tradeItemDAO = new TradeItemDAOImpl(); 28 | private ComputerDAO computerDAO = new ComputerDAOImpl(); 29 | 30 | public User getUserWithTrades(String username){ 31 | 32 | // ���� UserDAO �ķ�����ȡ User ���� 33 | User user = userDAO.getUser(username); 34 | if(user == null){ 35 | return null; 36 | } 37 | 38 | // ���� TradeDAO �ķ�����ȡ Trade �ļ��ϣ�����װ��Ϊ User ������ 39 | int userId = user.getUserId(); 40 | 41 | // ���� TradeItemDAO �ķ�����ȡÿһ�� Trade �е� TradeItem �ļ��ϣ�������װ��Ϊ Trade ������ 42 | Set trades = tradeDAO.getTradesWithUserId(userId); 43 | 44 | if(trades != null){ 45 | Iterator tradeIt = trades.iterator(); 46 | 47 | while(tradeIt.hasNext()){ 48 | Trade trade = tradeIt.next(); 49 | 50 | int tradeId = trade.getTradeId(); 51 | Set items = tradeItemDAO.getTradeItemsWithTradeId(tradeId); 52 | 53 | if(items != null){ 54 | for(TradeItem item: items){ 55 | item.setComputer(computerDAO.getComputer(item.getComputerId())); 56 | } 57 | 58 | if(items != null && items.size() != 0){ 59 | trade.setItems(items); 60 | } 61 | } 62 | 63 | if(items == null || items.size() == 0){ 64 | tradeIt.remove(); 65 | } 66 | 67 | } 68 | } 69 | 70 | if(trades != null && trades.size() != 0){ 71 | user.setTrades(trades); 72 | } 73 | 74 | return user; 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /src/com/xmut/estore/servlet/ComputerServlet.java: -------------------------------------------------------------------------------- 1 | package com.xmut.estore.servlet; 2 | 3 | import java.io.IOException; 4 | import java.lang.reflect.InvocationTargetException; 5 | import java.lang.reflect.Method; 6 | import java.util.HashMap; 7 | import java.util.Map; 8 | 9 | import javax.servlet.ServletException; 10 | import javax.servlet.annotation.WebServlet; 11 | import javax.servlet.http.HttpServlet; 12 | import javax.servlet.http.HttpServletRequest; 13 | import javax.servlet.http.HttpServletResponse; 14 | 15 | import com.xmut.estore.domain.ShoppingCart; 16 | import com.xmut.estore.web.EStoreWebUtils; 17 | import com.xmut.estore.service.UserService; 18 | import com.xmut.estore.domain.Account; 19 | import com.xmut.estore.domain.ShoppingCartItem; 20 | import com.xmut.estore.domain.User; 21 | import com.xmut.estore.service.AccountService; 22 | import com.xmut.estore.web.EStoreWebUtils; 23 | import com.google.gson.Gson; 24 | import com.xmut.estore.domain.Computer; 25 | import com.xmut.estore.service.ComputerService; 26 | import com.xmut.estore.web.CriteriaComputer; 27 | import com.xmut.estore.web.Page; 28 | 29 | public class ComputerServlet extends HttpServlet { 30 | 31 | private ComputerService computerService = new ComputerService(); 32 | 33 | private UserService userService = new UserService(); 34 | 35 | private AccountService accountService = new AccountService(); 36 | 37 | protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 38 | 39 | doPost(request, response); 40 | } 41 | 42 | 43 | 44 | //method反射机制调用方法 45 | @Override 46 | protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 47 | 48 | String methodName = request.getParameter("method"); 49 | 50 | try { 51 | // 利用反射获取方法 52 | Method method = getClass().getDeclaredMethod(methodName, HttpServletRequest.class,HttpServletResponse.class); 53 | // 执行相应的方法 54 | method.setAccessible(true); 55 | method.invoke(this, request,response); 56 | } catch (Exception e) { 57 | // TODO Auto-generated catch block 58 | e.printStackTrace(); 59 | } 60 | } 61 | protected void cash(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 62 | //1. 简单验证: 验证表单域的值是否符合基本的规范: 是否为空, 是否可以转为 int 类型, 是否是一个 email. 不需要进行查询 63 | //数据库或调用任何的业务方法. 64 | String username = request.getParameter("username"); 65 | String accountId = request.getParameter("accountId"); 66 | 67 | StringBuffer errors = validateFormField(username, accountId); 68 | 69 | //表单验证通过。 70 | if(errors.toString().equals("")){ 71 | errors = validateUser(username, accountId); 72 | 73 | //用户名和账号验证通过 74 | if(errors.toString().equals("")){ 75 | errors = validateComputerStoreNumber(request); 76 | 77 | //库存验证通过 78 | if(errors.toString().equals("")){ 79 | errors = validateBalance(request, accountId); 80 | } 81 | } 82 | } 83 | 84 | if(!errors.toString().equals("")){ 85 | request.setAttribute("errors", errors); 86 | request.getRequestDispatcher("/WEB-INF/pages/cash.jsp").forward(request, response); 87 | return; 88 | } 89 | 90 | //验证通过执行具体的逻辑操作 91 | computerService.cash(EStoreWebUtils.getShoppingCart(request), username, accountId); 92 | response.sendRedirect(request.getContextPath() + "/success.jsp"); 93 | } 94 | 95 | 96 | 97 | //验证余额是否充足 98 | public StringBuffer validateBalance(HttpServletRequest request, String accountId){ 99 | 100 | StringBuffer errors = new StringBuffer(""); 101 | ShoppingCart cart = EStoreWebUtils.getShoppingCart(request); 102 | 103 | Account account = accountService.getAccount(Integer.parseInt(accountId)); 104 | if(cart.getTotalMoney() > account.getBalance()){ 105 | errors.append("余额不足!"); 106 | } 107 | 108 | return errors; 109 | } 110 | 111 | //验证库存是否充足 112 | public StringBuffer validateComputerStoreNumber(HttpServletRequest request){ 113 | 114 | StringBuffer errors = new StringBuffer(""); 115 | ShoppingCart cart = EStoreWebUtils.getShoppingCart(request); 116 | 117 | for(ShoppingCartItem sci: cart.getItems()){ 118 | int quantity = sci.getQuantity(); 119 | int storeNumber = computerService.getComputer(sci.getComputer().getId()).getStoreNumber(); 120 | 121 | if(quantity > storeNumber){ 122 | errors.append(sci.getComputer().getBrand()+sci.getComputer().getModel() + "库存不足
"); 123 | } 124 | } 125 | 126 | return errors; 127 | } 128 | 129 | //验证用户名和账号是否匹配 130 | public StringBuffer validateUser(String username, String accountId){ 131 | boolean flag = false; 132 | User user = userService.getUserByUserName(username); 133 | if(user != null){ 134 | int accountId2 = user.getAccountId(); 135 | if(accountId.trim().equals("" + accountId2)){ 136 | flag = true; 137 | } 138 | } 139 | 140 | StringBuffer errors2 = new StringBuffer(""); 141 | if(!flag){ 142 | errors2.append("用户名和账号不匹配"); 143 | } 144 | 145 | return errors2; 146 | } 147 | 148 | //验证表单域是否符合基本的规则: 是否为空. 149 | public StringBuffer validateFormField(String username, String accountId){ 150 | StringBuffer errors = new StringBuffer(""); 151 | 152 | if(username == null || username.trim().equals("")){ 153 | errors.append("用户名不能为空
"); 154 | } 155 | 156 | if(accountId == null || accountId.trim().equals("")){ 157 | errors.append("账号不能为空"); 158 | } 159 | 160 | return errors; 161 | } 162 | 163 | protected void updateItemQuantity(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 164 | //4. 在 updateItemQuantity 方法中, 获取 quanity, id, 再获取购物车对象, 调用 service 的方法做修改 165 | String idStr = request.getParameter("id"); 166 | String quantityStr = request.getParameter("quantity"); 167 | 168 | ShoppingCart sc = EStoreWebUtils.getShoppingCart(request); 169 | 170 | int id = -1; 171 | int quantity = -1; 172 | 173 | try { 174 | id = Integer.parseInt(idStr); 175 | quantity = Integer.parseInt(quantityStr); 176 | } catch (Exception e) {} 177 | 178 | if(id > 0 && quantity > 0) 179 | computerService.updateItemQuantity(sc, id, quantity); 180 | 181 | //5. 传回 JSON 数据: computerNumber:xx, totalMoney 182 | Map result = new HashMap(); 183 | result.put("computerNumber", sc.getComputerNumber()); 184 | result.put("totalMoney", sc.getTotalMoney()); 185 | 186 | Gson gson = new Gson(); 187 | String jsonStr = gson.toJson(result); 188 | response.setContentType("text/javascript"); 189 | response.getWriter().print(jsonStr); 190 | } 191 | protected void remove(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 192 | String idStr = request.getParameter("id"); 193 | 194 | int id = -1; 195 | boolean flag = false; 196 | try { 197 | id = Integer.parseInt(idStr); 198 | } catch (Exception e) {} 199 | 200 | ShoppingCart sc = EStoreWebUtils.getShoppingCart(request); 201 | computerService.removeItemFromShoppingCart(sc, id); 202 | 203 | if(sc.isEmpty()){ 204 | request.getRequestDispatcher("/WEB-INF/pages/emptycart.jsp").forward(request, response); 205 | return; 206 | } 207 | 208 | request.getRequestDispatcher("/WEB-INF/pages/cart.jsp").forward(request, response); 209 | 210 | } 211 | protected void clear(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 212 | 213 | ShoppingCart sCart = EStoreWebUtils.getShoppingCart(request); 214 | computerService.clearShoppingCart(sCart); 215 | request.getRequestDispatcher("/WEB-INF/pages/emptycart.jsp").forward(request, response); 216 | } 217 | 218 | //跳转页面 219 | protected void forwardPage(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 220 | String page = request.getParameter("page"); 221 | request.getRequestDispatcher("/WEB-INF/pages/" + page + ".jsp").forward(request, response); 222 | } 223 | //添加到购物车 224 | protected void addToCart(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 225 | //1. 获取商品的 id 226 | String idStr = request.getParameter("id"); 227 | int id = -1; 228 | boolean flag = false; 229 | 230 | try { 231 | id = Integer.parseInt(idStr); 232 | } catch (Exception e) {} 233 | 234 | if(id > 0){ 235 | //2. 获取购物车对象 236 | ShoppingCart sc = EStoreWebUtils.getShoppingCart(request); 237 | 238 | //3. 调用 ComputerService 的 addToCart() 方法把商品放到购物车中 239 | flag = computerService.addToCart(id, sc); 240 | } 241 | 242 | if(flag){ 243 | //4. 直接调用 getComputers() 方法. 244 | getComputers(request, response); 245 | return; 246 | } 247 | 248 | response.sendRedirect(request.getContextPath() + "/error-1.jsp"); 249 | } 250 | //添加到购物车(商品详情页添加) 251 | protected void addToCartInside(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 252 | //1. 获取商品的 id 253 | String idStr = request.getParameter("id"); 254 | int id = -1; 255 | boolean flag = false; 256 | 257 | try { 258 | id = Integer.parseInt(idStr); 259 | } catch (Exception e) {} 260 | 261 | if(id > 0){ 262 | //2. 获取购物车对象 263 | ShoppingCart sc = EStoreWebUtils.getShoppingCart(request); 264 | 265 | //3. 调用 ComputerService 的 addToCart() 方法把商品放到购物车中 266 | flag = computerService.addToCart(id, sc); 267 | } 268 | 269 | if(flag){ 270 | //4. 直接调用 getComputer() 方法. 271 | getComputer(request, response); 272 | return; 273 | } 274 | 275 | response.sendRedirect(request.getContextPath() + "/error-1.jsp"); 276 | } 277 | protected void getComputer(HttpServletRequest request,HttpServletResponse response) throws IOException, ServletException { 278 | String idStr = request.getParameter("id"); 279 | int id = -1; 280 | Computer computer = null; 281 | 282 | try { 283 | id = Integer.parseInt(idStr); 284 | } catch (NumberFormatException e) {} 285 | if (id > 0) { 286 | computer = computerService.getComputer(id); 287 | } 288 | 289 | if (computer == null) { 290 | response.sendRedirect(request.getContextPath()+"/error-1.jsp"); 291 | return; 292 | } 293 | request.setAttribute("computer", computer); 294 | request.getRequestDispatcher("/WEB-INF/pages/computer.jsp").forward(request, response); 295 | } 296 | protected void getComputers(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 297 | String pageNoStr = request.getParameter("pageNo"); 298 | String minPriceStr = request.getParameter("minPrice"); 299 | String maxPriceStr = request.getParameter("maxPrice"); 300 | 301 | 302 | int pageNo = 1; 303 | int minPrice = 0; 304 | int maxPrice = Integer.MAX_VALUE; 305 | 306 | try { 307 | pageNo = Integer.parseInt(pageNoStr); 308 | } catch (NumberFormatException e) {} 309 | 310 | try { 311 | minPrice = Integer.parseInt(minPriceStr); 312 | } catch (NumberFormatException e) {} 313 | 314 | try { 315 | maxPrice = Integer.parseInt(maxPriceStr); 316 | } catch (NumberFormatException e) {} 317 | 318 | CriteriaComputer criteriaComputer = new CriteriaComputer(minPrice, maxPrice, pageNo); 319 | Page page = computerService.getPage(criteriaComputer); 320 | 321 | request.setAttribute("computerpage", page); 322 | request.getRequestDispatcher("/WEB-INF/pages/computers.jsp").forward(request, response); 323 | } 324 | 325 | 326 | } 327 | -------------------------------------------------------------------------------- /src/com/xmut/estore/servlet/UserServlet.java: -------------------------------------------------------------------------------- 1 | package com.xmut.estore.servlet; 2 | 3 | import java.io.IOException; 4 | import javax.servlet.ServletException; 5 | import javax.servlet.http.HttpServlet; 6 | import javax.servlet.http.HttpServletRequest; 7 | import javax.servlet.http.HttpServletResponse; 8 | 9 | import com.xmut.estore.domain.User; 10 | import com.xmut.estore.service.UserService; 11 | /** 12 | * Servlet implementation class UserServlet 13 | */ 14 | public class UserServlet extends HttpServlet { 15 | 16 | private static final long serialVersionUID = 1L; 17 | 18 | private UserService userService = new UserService(); 19 | 20 | protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 21 | // 获取 username 请求参数的值 22 | String username = request.getParameter("username"); 23 | 24 | // 调用 UserService 的 getUser(username) 获取User 对象:要求 trades 是被装配好的,而且每一个 Trrade 对象的 items 也被装配好 25 | User user = userService.getUserWithTrades(username); 26 | 27 | // 把 User 对象放入到 request 中 28 | if(user == null){ 29 | response.sendRedirect(request.getServletPath() + "/error-1.jsp"); 30 | return; 31 | } 32 | 33 | request.setAttribute("user", user); 34 | 35 | // 转发页面到 /WEB-INF/pages/trades.jsp 36 | request.getRequestDispatcher("/WEB-INF/pages/trades.jsp").forward(request, response); 37 | 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/com/xmut/estore/test/BaseDAOTest.java: -------------------------------------------------------------------------------- 1 | package com.xmut.estore.test; 2 | 3 | import static org.junit.jupiter.api.Assertions.fail; 4 | 5 | import org.junit.jupiter.api.Test; 6 | import java.sql.Date; 7 | import java.util.List; 8 | 9 | import com.xmut.estore.dao.impl.BaseDAO; 10 | import com.xmut.estore.dao.impl.ComputerDAOImpl; 11 | import com.xmut.estore.domain.Computer; 12 | 13 | class BaseDAOTest { 14 | 15 | 16 | private ComputerDAOImpl computerDAOImpl = new ComputerDAOImpl(); 17 | private BaseDAO baseDAO = new BaseDAO(); 18 | @Test 19 | void testInsert() { 20 | String sql = "INSERT INTO trade (userid,tradetime) VALUES(?,?)"; 21 | long id = computerDAOImpl.insert(sql, 1,new Date(new java.util.Date().getTime())); 22 | System.out.println(id); 23 | } 24 | 25 | @Test 26 | void testUpdate() { 27 | 28 | String sql = "UPDATE mycomputers SET salesAmount = ? WHERE id = ?"; 29 | computerDAOImpl.update(sql, 100, 4); 30 | 31 | } 32 | 33 | @Test 34 | void testQuery() { 35 | String sql = "SELECT id,brand,model,price,publishingDate"+ 36 | "salesAmount,storeNumber,remark FROM mycomputers WHERE id = ?"; 37 | Computer computer = computerDAOImpl.query(sql, 6); 38 | System.out.println(computer); 39 | } 40 | 41 | @Test 42 | void testQueryForList() { 43 | String sql = "SELECT id,brand,model,price,publishingDate"+ 44 | "salesAmount,storeNumber,remark FROM mycomputers WHERE id < ?"; 45 | List computers = computerDAOImpl.queryForList(sql, 4); 46 | System.out.println(computers); 47 | } 48 | 49 | @Test 50 | void testGetSingleVal() { 51 | String sql = "SELECT count(id) FROM mycomputers"; 52 | long count = computerDAOImpl.getSingleVal(sql); 53 | System.out.println(count); 54 | } 55 | 56 | @Test 57 | void testBatch() { 58 | String sql = "UPDATE mycomputers "+ 59 | "SET salesAmount = ?, storeNumber = ? WHERE id = ?"; 60 | computerDAOImpl.batch(sql, new Object[]{1,1,1},new Object[]{2,2,2},new Object[]{3,3,3}); 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /src/com/xmut/estore/test/ComputerDAOTest.java: -------------------------------------------------------------------------------- 1 | package com.xmut.estore.test; 2 | 3 | import static org.junit.jupiter.api.Assertions.*; 4 | 5 | import org.junit.jupiter.api.Test; 6 | 7 | import com.xmut.estore.dao.ComputerDAO; 8 | import com.xmut.estore.dao.impl.ComputerDAOImpl; 9 | import com.xmut.estore.domain.Computer; 10 | import com.xmut.estore.web.CriteriaComputer; 11 | import com.xmut.estore.web.Page; 12 | 13 | class ComputerDAOTest { 14 | private ComputerDAO computerDAO = new ComputerDAOImpl(); 15 | 16 | @Test 17 | void testGetComputer() { 18 | Computer computer = computerDAO.getComputer(1); 19 | System.out.println(computer); 20 | } 21 | 22 | @Test 23 | void testGetPage() { 24 | CriteriaComputer cc = new CriteriaComputer(0, Integer.MAX_VALUE, 3); 25 | Page page = computerDAO.getPage(cc); 26 | 27 | System.out.println("pageNo: "+ page.getPageNo()); 28 | System.out.println("totalPageNumber: "+page.getTotalPageNumber()); 29 | System.out.println("list: "+page.getList()); 30 | System.out.println("prevPage: "+page.getPrevPage()); 31 | System.out.println("nextPage: "+page.getNextPage()); 32 | 33 | } 34 | 35 | @Test 36 | void testGetTotalComputerNumber() { 37 | fail("Not yet implemented"); 38 | } 39 | 40 | @Test 41 | void testGetPageList() { 42 | fail("Not yet implemented"); 43 | } 44 | 45 | @Test 46 | void testGetStoreNumber() { 47 | int storeNumber = computerDAO.getStoreNumber(5); 48 | System.out.println(storeNumber); 49 | } 50 | @Test 51 | void testGetComputerImgUrl() { 52 | String url = computerDAO.getComputerImgUrl(1); 53 | System.out.println(url); 54 | 55 | } 56 | @Test 57 | void testBatchUpdateStoreNumberAndSalesAmount() { 58 | fail("Not yet implemented"); 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/com/xmut/estore/utils/ReflectionUtils.java: -------------------------------------------------------------------------------- 1 | package com.xmut.estore.utils; 2 | 3 | 4 | import java.lang.reflect.Field; 5 | import java.lang.reflect.InvocationTargetException; 6 | import java.lang.reflect.Method; 7 | import java.lang.reflect.Modifier; 8 | import java.lang.reflect.ParameterizedType; 9 | import java.lang.reflect.Type; 10 | 11 | /** 12 | * 反射的 Utils 函数集合 13 | * 提供访问私有变量, 获取泛型类型 Class, 提取集合中元素属性等 Utils 函数 14 | * @author Administrator 15 | * 16 | */ 17 | public class ReflectionUtils { 18 | 19 | 20 | /** 21 | * 通过反射, 获得定义 Class 时声明的父类的泛型参数的类型 22 | * 如: public EmployeeDao extends BaseDao 23 | * @param clazz 24 | * @param index 25 | * @return 26 | */ 27 | @SuppressWarnings("unchecked") 28 | public static Class getSuperClassGenricType(Class clazz, int index){ 29 | Type genType = clazz.getGenericSuperclass(); 30 | 31 | if(!(genType instanceof ParameterizedType)){ 32 | return Object.class; 33 | } 34 | 35 | Type [] params = ((ParameterizedType)genType).getActualTypeArguments(); 36 | 37 | if(index >= params.length || index < 0){ 38 | return Object.class; 39 | } 40 | 41 | if(!(params[index] instanceof Class)){ 42 | return Object.class; 43 | } 44 | 45 | return (Class) params[index]; 46 | } 47 | 48 | /** 49 | * 通过反射, 获得 Class 定义中声明的父类的泛型参数类型 50 | * 如: public EmployeeDao extends BaseDao 51 | * @param 52 | * @param clazz 53 | * @return 54 | */ 55 | @SuppressWarnings("unchecked") 56 | public static Class getSuperGenericType(Class clazz){ 57 | return getSuperClassGenricType(clazz, 0); 58 | } 59 | 60 | /** 61 | * 循环向上转型, 获取对象的 DeclaredMethod 62 | * @param object 63 | * @param methodName 64 | * @param parameterTypes 65 | * @return 66 | */ 67 | public static Method getDeclaredMethod(Object object, String methodName, Class[] parameterTypes){ 68 | 69 | for(Class superClass = object.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()){ 70 | try { 71 | //superClass.getMethod(methodName, parameterTypes); 72 | return superClass.getDeclaredMethod(methodName, parameterTypes); 73 | } catch (NoSuchMethodException e) { 74 | //Method 不在当前类定义, 继续向上转型 75 | } 76 | //.. 77 | } 78 | 79 | return null; 80 | } 81 | 82 | /** 83 | * 使 filed 变为可访问 84 | * @param field 85 | */ 86 | public static void makeAccessible(Field field){ 87 | if(!Modifier.isPublic(field.getModifiers())){ 88 | field.setAccessible(true); 89 | } 90 | } 91 | 92 | /** 93 | * 循环向上转型, 获取对象的 DeclaredField 94 | * @param object 95 | * @param filedName 96 | * @return 97 | */ 98 | public static Field getDeclaredField(Object object, String filedName){ 99 | 100 | for(Class superClass = object.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()){ 101 | try { 102 | return superClass.getDeclaredField(filedName); 103 | } catch (NoSuchFieldException e) { 104 | //Field 不在当前类定义, 继续向上转型 105 | } 106 | } 107 | return null; 108 | } 109 | 110 | /** 111 | * 直接调用对象方法, 而忽略修饰符(private, protected) 112 | * @param object 113 | * @param methodName 114 | * @param parameterTypes 115 | * @param parameters 116 | * @return 117 | * @throws InvocationTargetException 118 | * @throws IllegalArgumentException 119 | */ 120 | public static Object invokeMethod(Object object, String methodName, Class [] parameterTypes, 121 | Object [] parameters) throws InvocationTargetException{ 122 | 123 | Method method = getDeclaredMethod(object, methodName, parameterTypes); 124 | 125 | if(method == null){ 126 | throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + object + "]"); 127 | } 128 | 129 | method.setAccessible(true); 130 | 131 | try { 132 | return method.invoke(object, parameters); 133 | } catch(IllegalAccessException e) { 134 | System.out.println("不可能抛出的异常"); 135 | } 136 | 137 | return null; 138 | } 139 | 140 | /** 141 | * 直接设置对象属性值, 忽略 private/protected 修饰符, 也不经过 setter 142 | * @param object 143 | * @param fieldName 144 | * @param value 145 | */ 146 | public static void setFieldValue(Object object, String fieldName, Object value){ 147 | Field field = getDeclaredField(object, fieldName); 148 | 149 | if (field == null) 150 | throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + object + "]"); 151 | 152 | makeAccessible(field); 153 | 154 | try { 155 | field.set(object, value); 156 | } catch (IllegalAccessException e) { 157 | System.out.println("不可能抛出的异常"); 158 | } 159 | } 160 | 161 | /** 162 | * 直接读取对象的属性值, 忽略 private/protected 修饰符, 也不经过 getter 163 | * @param object 164 | * @param fieldName 165 | * @return 166 | */ 167 | public static Object getFieldValue(Object object, String fieldName){ 168 | Field field = getDeclaredField(object, fieldName); 169 | 170 | if (field == null) 171 | throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + object + "]"); 172 | 173 | makeAccessible(field); 174 | 175 | Object result = null; 176 | 177 | try { 178 | result = field.get(object); 179 | } catch (IllegalAccessException e) { 180 | System.out.println("不可能抛出的异常"); 181 | } 182 | 183 | return result; 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /src/com/xmut/estore/web/ConnectionContext.java: -------------------------------------------------------------------------------- 1 | package com.xmut.estore.web; 2 | 3 | import java.sql.Connection; 4 | 5 | public class ConnectionContext { 6 | 7 | private ConnectionContext(){} 8 | 9 | private static ConnectionContext instance = new ConnectionContext(); 10 | 11 | public static ConnectionContext getInstance() { 12 | return instance; 13 | } 14 | 15 | private ThreadLocal connectionThreadLocal = 16 | new ThreadLocal<>(); 17 | 18 | public void bind(Connection connection){ 19 | connectionThreadLocal.set(connection); 20 | } 21 | 22 | public Connection get(){ 23 | return connectionThreadLocal.get(); 24 | } 25 | 26 | public void remove(){ 27 | connectionThreadLocal.remove(); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/com/xmut/estore/web/CriteriaComputer.java: -------------------------------------------------------------------------------- 1 | package com.xmut.estore.web; 2 | 3 | public class CriteriaComputer { 4 | //封装查询条件的CriteriaComputer类 5 | private float minPrice = 0; 6 | private float maxPrice = Integer.MAX_VALUE; 7 | private int pageNo; 8 | 9 | public CriteriaComputer(float minPrice, float maxPrice, int pageNo) { 10 | super(); 11 | this.minPrice = minPrice; 12 | this.maxPrice = maxPrice; 13 | this.pageNo = pageNo; 14 | } 15 | 16 | public float getMinPrice() { 17 | return minPrice; 18 | } 19 | public void setMinPrice(float minPrice) { 20 | this.minPrice = minPrice; 21 | } 22 | public float getMaxPrice() { 23 | return maxPrice; 24 | } 25 | public void setMaxPrice(float maxPrice) { 26 | this.maxPrice = maxPrice; 27 | } 28 | public int getPageNo() { 29 | return pageNo; 30 | } 31 | public void setPageNo(int pageNo) { 32 | this.pageNo = pageNo; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/com/xmut/estore/web/EStoreWebUtils.java: -------------------------------------------------------------------------------- 1 | package com.xmut.estore.web; 2 | 3 | import javax.servlet.http.HttpServletRequest; 4 | import javax.servlet.http.HttpSession; 5 | 6 | import com.xmut.estore.domain.ShoppingCart; 7 | 8 | public class EStoreWebUtils { 9 | /** 10 | * 获取购物车对象: 从 session 中获取, 若 session 中没有改对象. 11 | * 则创建一个新的购物车对象, 放入到 session 中. 12 | * 若有, 则直接返回. 13 | * @param request 14 | * @return 15 | */ 16 | public static ShoppingCart getShoppingCart(HttpServletRequest request){ 17 | HttpSession session = request.getSession(); 18 | 19 | ShoppingCart sc = (ShoppingCart) session.getAttribute("ShoppingCart"); 20 | if(sc == null){ 21 | sc = new ShoppingCart(); 22 | session.setAttribute("ShoppingCart", sc); 23 | } 24 | 25 | return sc; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/com/xmut/estore/web/Page.java: -------------------------------------------------------------------------------- 1 | package com.xmut.estore.web; 2 | 3 | import java.util.List; 4 | 5 | public class Page { 6 | 7 | //当前第几页 8 | private int pageNo; 9 | 10 | //当前页的 List 11 | private List list; 12 | 13 | //每页显示多少条记录 14 | private int pageSize = 6; 15 | 16 | //共有多少条记录 17 | private long totalItemNumber; 18 | 19 | //构造器中需要对 pageNo 进行初始化 20 | public Page(int pageNo) { 21 | super(); 22 | this.pageNo = pageNo; 23 | } 24 | 25 | //校验页数是否合法 26 | public int getPageNo() { 27 | if(pageNo < 0) 28 | pageNo = 1; 29 | 30 | if(pageNo > getTotalPageNumber()){ 31 | pageNo = getTotalPageNumber(); 32 | } 33 | 34 | return pageNo; 35 | } 36 | 37 | public int getPageSize() { 38 | return pageSize; 39 | } 40 | 41 | public void setList(List list) { 42 | this.list = list; 43 | } 44 | 45 | public List getList() { 46 | return list; 47 | } 48 | 49 | //获取总页数 50 | public int getTotalPageNumber(){ 51 | 52 | int totalPageNumber = (int)totalItemNumber / pageSize; 53 | 54 | if(totalItemNumber % pageSize != 0){ 55 | totalPageNumber++; 56 | } 57 | 58 | return totalPageNumber; 59 | } 60 | 61 | public void setTotalItemNumber(long totalItemNumber) { 62 | this.totalItemNumber = totalItemNumber; 63 | } 64 | 65 | public boolean isHasNext(){ 66 | if(getPageNo() < getTotalPageNumber()){ 67 | return true; 68 | } 69 | 70 | return false; 71 | } 72 | 73 | public boolean isHasPrev(){ 74 | if(getPageNo() > 1){ 75 | return true; 76 | } 77 | 78 | return false; 79 | } 80 | 81 | public int getPrevPage(){ 82 | if(isHasPrev()){ 83 | return getPageNo() - 1; 84 | } 85 | 86 | return getPageNo(); 87 | } 88 | 89 | public int getNextPage(){ 90 | if(isHasNext()){ 91 | return getPageNo() + 1; 92 | } 93 | 94 | return getPageNo(); 95 | } 96 | } 97 | --------------------------------------------------------------------------------