基于JSP+MySQL实现(Web)校园网上订餐系统
校园网上订餐系统
1 需求分析
在此校园网上订餐系统设计中,要求实现后台和前台两种不同的操作方式,其中前台要求实现新增菜品、菜品价格调整、菜品下架、销量统计(按日、月)、用户订单维护等功能,而在后台管理系统中,应实现菜品列表、用户注册、在线下单等功能。经由与团队开发人员商定,由本人负责订单模块设计与实现,由团队其他两人负责菜品模块以及用户模块的开发,以下仅对订单模块进行需求分析。
在订单模块设计中,需要开发人员完成的功能主要有:
(1)后台管理员需要完成前台用户请求订单的相关处理与维护功能。
(2)后台管理员还需要可以对销售的所有相关订单以及历史订单按照用户 ID、菜品名称、销售日期等方式进行查询。
(3)用户在前台也可以查看自己的待提交或者已经提交的订单表,以及历史订单。
(4)用户在前台也可以按照菜品名称和销售日期进行查询自己的订单。
(5)后台管理员可以统计本日的销售额以及订单。
2 概要设计
2.1 外部设计
2.1.1 标识符和状态
数据库软件的名称:MySQL 5.6
数据库的名称:apsfc
2.1.2 命名约定
所有的数据库表单的命名都是以模块的英文词汇组成,这样能够统一数据库表的命名,也能够更好的规范数据库表命名。
2.1.3 设计约定
在本系统中,数据库的设计采用在线绘图工具 ProcessOn 进行,并且采用面向对象的设计方法,首先进行对象实体的设计,最后将对象持久化到数据库中,所有的表和表之间的关联(ER 图)都采用 PowerDesigner 工具进行,这样能够将整个系统的设计和数据库设计有机的结合起来。
2.2 概念结构设计
2.2.1 实体和属性的定义
订单模块
订单(订单 ID,用户 ID,菜品 ID,菜品订单总数,订单时间,订单处理)
图 1 订单信息
会员(会员 ID,昵称,登录密码,真实姓名,性别,年龄,身份证号,配送地址,联系方式,邮政编码,会员属性)。
图 2 会员信息
菜品(菜品 ID,菜名,菜品,类别 id,原料,说明,大众价格,大众价格所卖出的总数,会员价格,会员价格所卖出的的总数,图片路径)。
图 3 菜品信息
菜品类别(菜品类别 ID,菜品类别名)
图 4 菜品类别信息
管理员(管理员 ID,管理员姓名,登录密码,管理权限)
图 5 管理员信息
2.2.2 订单模块功能设计
图 6 订单模块功能设计
2.2.3 ER 图设计
图 7 ER 图设计
2.2.4 数据库完整性约束
(1)订单表 orders 中的 userid 参照用户信息表 users 中的 id 完整性定义。
ALTER TABLE `users` ADD CONSTRAINT `id_key` FOREIGN KEY (`id`) REFERENCES `orders` (`userid`) ON DELETE SET NULL ON UPDATE SET NULL;
(2)订单表 orders 中的 menuid 应参照菜品表 menus 中的 id 完整性定义。
ALTER TABLE `apsfc`.`orders` ADD INDEX (`menuid`);ALTER TABLE `menus` ADD CONSTRAINT `cai_key` FOREIGN KEY (`id`) REFERENCES `orders` (`menuid`) ON DELETE CASCADE ON UPDATE CASCADE;
(3)菜品表 menus 中的 typeid 应参照菜品类别表 types 中的 id 进行完整性约束。
ALTER TABLE `types` ADD CONSTRAINT `types` FOREIGN KEY (`id`) REFERENCES `menus` (`typeid`) ON DELETE SET NULL ON UPDATE RESTRICT;
2.3 逻辑结构设计
2.3.1 模式设计
订单信息表主要记录用户所选菜品以及创建时间等基本信息。
字段名
数据类型
长度
小数点
允许空值
主键
描述
id
int
4
0
否
是
唯一标识 ID
userid
int
4
0
否
用户 ID
menuid
int
4
0
否
菜品 ID
menusum
int
4
0
否
订单总数
times
varchar
20
0
否
订单创建时间
delivery
int
4
0
否
是否送达 0 已送达 1 未送达
表 1 orders 结构表
菜品信息表主要描述菜品所属种类以及价格等相关信息。
字段名
数据类型
长度
小数点
允许空值
主键
描述
id
int
4
0
否
是
菜品唯一标识
name
varchar
20
0
否
菜品名
typeid
int
4
0
否
菜品类别 id
burden
varchar
50
0
否
原料
brief
varchar
500
0
否
说明
price
decimal
10
2
否
大众价格
sums
int
4
0
否
大众价格所卖出的总数
price1
decimal
10
2
否
会员价格
sums1
int
4
0
否
会员价格所卖出的的总数
imgpath
varchar
50
0
是
图片路径
表 2 menus 结构表
会员信息表主要存储会员名以及电话、需要派送的地址等相关信息。
字段名
数据类型
长度
小数点
允许空值
主键
描述
id
varchar
4
0
否
是
用户唯一标识
name
varchar
20
0
否
用户姓名
pwd
int
20
0
否
用户登录密码
realname
varchar
20
0
否
用户真实姓名
sex
varchar
10
0
否
用户性别
age
varchar
4
0
否
用户年龄
card
varchar
20
0
否
用户身份证号
address
varchar
100
0
否
用户订单地址
phone
varchar
20
0
否
用户联系方式
varchar
20
0
是
用户的联系邮箱
code
varchar
10
0
是
用户邮政编码
type
int
4
0
否
用户类型(默认为 0)
表 3 users 结构表
菜品类型信息表主要描述菜品所属种类。
字段名
数据类型
长度
小数点
允许空值
主键
描述
id
int
4
0
否
是
菜品类型唯一标识
name
varchar
20
0
否
否
菜品类名
表 4 types 结构表
管理员信息表主要是 s 存储管理员的相关信息,只有拥有管理员权限的用户才可以登录后台管理系统。
字段名
数据类型
长度
小数点
允许空值
主键
描述
id
int
4
0
否
是
管理员类型唯一标识
name
varchar
20
0
否
否
管理员姓名
authority
varchar
10
0
否
否
管理员权限
表 5 admin 结构表
2.3.2 外模式设计
用户视图设计:通过建立订单表的用户视图,使得其达到简化用户操作,使用户能以多种角度看待同一数据的作用,利用视图可以更清晰的表达查询,同时也增加了数据库的安全性。
(1)创建视图 v_orders 用于用户按照日期进行查询订单
create view v_orders as select c.id as id,a.id as userid,b.id as menuid,c.id as orderid,realname,phone,address,b.name as menuname,menusum,price1,times,delivery from users a,menus b,orders c where a.id=c.userid and b.id=c.menuid and c.times like \'%\"+ date + \"%\'group by c.id
(2)创建用户视图 v_orders2 用于用户按照菜品进行查找。
create view v_orders1 as select c.id as id,a.id as userid,b.id as menuid,c.id as orderid,realname,phone,address,b.name as menuname,menusum,price1,times,delivery from users a,menus b,orders c where a.id=c.userid and b.id=c.menuid and b.name like \'%\"+ menuname + \"%\'GROUP BY c.id
(3)创建用户视图 v_orders3 便于用户进行按照用户 ID 进行查找
create view v_orders2as select c.id as id,a.id as userid,b.id as menuid,c.id as orderid,realname,phone,address,b.name as menuname,menusum,price1,times,delivery from users a,menus b,orders c where a.id=c.userid and b.id=c.menuid and c.userid=userid
2.4 物理结构设计
2.4.1 建立索引
(1)为订单模块建立相关的索引使得加快数据的检索速度,实现提高系统性能。
CREATE INDEX index_name ON table_name (column_list)
2.4.2 存储过程
(1)创建存储过程,使其可以执行 SQL 语句
create PROCEDURE EXECUTE_sql_proc(IN executeSql varchar(1000))BEGIN set @needExcSql:=executeSql;PREPARE stmt from @needExcSql;EXECUTE stmt;DEALLOCATE PREPARE stmt;END
(2)创建存储过程,模糊查询指定日期的订单 ID
DROP PROCEDURE if EXISTS get_orders_id;CREATE PROCEDURE get_orders_id(in $tableName varchar(25), in $times varchar(20))set @sql=CONCAT(\'select id into @mainID from\',$tableName,\'where times like\',$times,\'%\',\'order by times limit 1\' );PREPARE stmt1 from @sql;EXECUTE stmt1;DEALLOCATE PREPARE stmt1;END;
2.4.3 触发器
(1)为订单模块设计触发器以达到对相关信息进行条件约束的目的。
① 限制 delivery 只能为 1 或者 0
CREATE TRIGGER ` Insert_Or_Update_Orders` AFTER INSERT ON `orders`FOR EACH ROW if exists(select *from INSERTED where delivery!=1 and delivery!=0)rollback;
② 限制用户一次订单总数不能超过 100 单。
CREATE TRIGGER tg_orders_before_create BEFORE INSERT ON orders FOR EACH ROW BEGIN set @count = (SELECT menusum FROM orders WHERE NEW.menusum=menusum ); if @count > 100 then SIGNAL SQLSTATE \'TX000\' SET MESSAGE_TEXT = \'beyond the max num\'; end if; END;
2.5 数据库实施设计
2.5.1 数据库实现
Navicat MySQL Data Transfer
Source Server : evan
Source Server Version : 50717
Source Host : localhost:3306
Source Database : apsfc
Target Server Type : MySQL
Target Server Version : 50717
File Encoding : 65001
Date: 2018-01-12 10:04:07
2.5.2 订单表设计
(1)表 orders 中的 SQL 语句如下所示:
-- ------------------------------ Table structure for `orders`-- ----------------------------DROP TABLE IF EXISTS `orders`;CREATE TABLE `orders` ( `id` int(4) NOT NULL AUTO_INCREMENT, `userid` int(4) unsigned NOT NULL, `menuid` int(4) unsigned NOT NULL, `menusum` int(4) unsigned NOT NULL, `times` varchar(20) NOT NULL, `delivery` int(4) unsigned NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `id` (`id`), KEY `index_orders` (`id`,`userid`,`menuid`,`menusum`,`times`,`delivery`)) ENGINE=InnoDB AUTO_INCREMENT=32 DEFAULT CHARSET=utf8;
(2)试运行及相关测试语句如下:
-- ------------------------------ Records of orders-- ----------------------------INSERT INTO `orders` VALUES (\'16\', \'2\', \'12\', \'2\', \'2018-01-07 13:16:28\', \'1\');INSERT INTO `orders` VALUES (\'17\', \'1\', \'14\', \'1\', \'2018-01-07 13:23:30\', \'1\');INSERT INTO `orders` VALUES (\'19\', \'4\', \'15\', \'2\', \'2018-01-07 23:26:20\', \'1\');INSERT INTO `orders` VALUES (\'23\', \'4\', \'14\', \'1\', \'2015-01-07 00:35:09\', \'1\');INSERT INTO `orders` VALUES (\'24\', \'4\', \'17\', \'1\', \'2018-01-07 00:35:09\', \'1\');INSERT INTO `orders` VALUES (\'25\', \'2\', \'15\', \'1\', \'2018-01-07 20:14:23\', \'1\');INSERT INTO `orders` VALUES (\'27\', \'2\', \'18\', \'1\', \'2018-01-07 20:31:56\', \'1\');INSERT INTO `orders` VALUES (\'28\', \'2\', \'19\', \'1\', \'2018-01-07 20:31:56\', \'0\');INSERT INTO `orders` VALUES (\'29\', \'4\', \'15\', \'1\', \'2018-01-05 19:16:00\', \'0\');INSERT INTO `orders` VALUES (\'30\', \'4\', \'14\', \'1\', \'2018-01-08 17:38:50\', \'0\');INSERT INTO `orders` VALUES (\'31\', \'4\', \'15\', \'1\', \'2018-01-09 10:35:36\', \'0\');
2.5.3 管理员信息表设计
(1)表 admin 中的 SQL 语句如下所示:
- ------------------------------ Table structure for `admin`-- ----------------------------DROP TABLE IF EXISTS `admin`;CREATE TABLE `admin` ( `id` int(4) NOT NULL AUTO_INCREMENT, `name` varchar(20) NOT NULL, `pwd` varchar(20) NOT NULL, `authority` varchar(10) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `id` (`id`)) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
(2) 试运行及相关测试语句如下:
-- ------------------------------ Records of admin-- ----------------------------INSERT INTO `admin` VALUES (\'1\', \'sa\', \'sa\', \'0\');INSERT INTO `admin` VALUES (\'2\', \'admin\', \'admin\', \'0\');INSERT INTO `admin` VALUES (\'3\', \'张三\', \'3\', \'0\');INSERT INTO `admin` VALUES (\'4\', \'sas\', \'1\', \'0\');
2.5.4 菜品表信息设计
(1)表 menus 中的 SQL 语句如下所示:
-- ------------------------------ Table structure for `menus`-- ----------------------------DROP TABLE IF EXISTS `menus`;CREATE TABLE `menus` ( `id` int(4) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(20) NOT NULL, `typeid` int(4) unsigned NOT NULL, `burden` varchar(50) NOT NULL, `brief` varchar(500) NOT NULL, `price` decimal(10,2) unsigned NOT NULL, `sums` int(4) unsigned NOT NULL DEFAULT \'0\', `price1` decimal(10,2) unsigned NOT NULL, `sums1` int(4) unsigned NOT NULL DEFAULT \'0\', `imgpath` varchar(50) DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE, UNIQUE KEY `id` (`id`)) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8;
(2) 试运行及相关测试语句如下:
-- ------------------------------ Records of menus-- ----------------------------INSERT INTO `menus` VALUES (\'12\', \'粉蒸肉\', \'10\', \'米粉、五花肉\', \'暂无\', \'26.00\', \'0\', \'23.00\', \'0\', \'img/m_fenzhengrou.gif\');INSERT INTO `menus` VALUES (\'14\', \'糖醋排骨\', \'2\', \'排骨、糖、醋\', \'暂无\', \'26.00\', \'0\', \'24.00\', \'4\', \'img/m_tangcupaigu.gif\');INSERT INTO `menus` VALUES (\'15\', \'咸肉菜饭\', \'1\', \'咸肉、米饭\', \'暂无\', \'15.00\', \'0\', \'12.00\', \'4\', \'img/m_xianroucaifan.gif\');INSERT INTO `menus` VALUES (\'17\', \'五香驴肉\', \'1\', \'驴肉\', \'暂无\', \'25.00\', \'0\', \'21.00\', \'1\', \'img/m_wuxianglvrou.gif\');INSERT INTO `menus` VALUES (\'18\', \'黄瓜拉皮\', \'1\', \'黄瓜、拉皮\', \'暂无\', \'8.00\', \'0\', \'6.00\', \'1\', \'img/m_huanggualapi.gif\');INSERT INTO `menus` VALUES (\'19\', \'水煮鱼\', \'11\', \'鱼,辣椒\', \'暂无\', \'38.00\', \'0\', \'32.00\', \'1\', \'img/m_shuizhuyu.gif\');
2.5.5 用户信息表设计
-- ------------------------------ Table structure for `users`-- ----------------------------DROP TABLE IF EXISTS `users`;CREATE TABLE `users` ( `id` int(4) NOT NULL AUTO_INCREMENT, `name` varchar(20) NOT NULL, `pwd` varchar(20) NOT NULL, `realname` varchar(20) NOT NULL, `sex` varchar(10) NOT NULL, `age` int(4) unsigned NOT NULL, `card` varchar(20) NOT NULL, `address` varchar(100) NOT NULL DEFAULT \'\' COMMENT \'address\', `phone` varchar(20) NOT NULL, `email` varchar(20) DEFAULT NULL, `code` varchar(10) DEFAULT NULL, `type` int(4) unsigned NOT NULL DEFAULT \'0\', PRIMARY KEY (`id`) USING BTREE, UNIQUE KEY `id` (`id`)) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;
(2)试运行及相关测试语句如下
-- ------------------------------ Records of users-- ----------------------------INSERT INTO `users` VALUES (\'2\', \'222\', \'222\', \'2221\', \'女\', \'241\', \'211111111111111111\', \'郑州市高新区\', \'13988888888\', \'123@163.com\', \'110044\', \'0\');INSERT INTO `users` VALUES (\'3\', \'sunday\', \'123\', \'张三\', \'男\', \'26\', \'4222222222222222\', \'郑州市高新区\', \'13901001111\', \'13901001111@139.com\', \'101000\', \'0\');INSERT INTO `users` VALUES (\'4\', \'1\', \'1\', \'李二狗\', \'男\', \'1\', \'1\', \'郑州市高新区\', \'1\', \'1\', \'1\', \'0\');INSERT INTO `users` VALUES (\'8\', \'炸支付\', \'4565\', \'赵志国\', \'男\', \'45\', \'410621199709284517\', \'郑州市高新区\', \'13253312194\', \'456250@111.com\', \'45445\', \'0\');INSERT INTO `users` VALUES (\'9\', \'evan\', \'888333\', \'王权\', \'男\', \'56\', \'456464546545654\', \'郑州市高新区\', \'2343434\', \'45654545@qq.com\', \'456250\', \'0\');INSERT INTO `users` VALUES (\'10\', \'fas\', \'fa\', \'fasd\', \'男\', \'12\', \'324254345345\', \'郑州市高新区dfadf\', \'13121555\', \'32433@adsfs\', \'4533\', \'0\');
3 运行环境
3.1 软件环境
win10 操作系统
3.2 硬件环境
Lenovo G50-70 笔记本电脑
4 开发工具和编程语言
4.1 开发工具
4.1.1 编程开发工具
MyEclipse2016 、MySQL 5.6 版本、Navicat for MySQL
4.1.2 图形设计工具
ProcessOn、PhotoShop2017 、powerDesigner
4.2 编程语言
JSP、JavaScript、CSS 、Java
5 详细设计
5.1 数据库操作设计
5.1.1 数据库的连接与关闭
public class DBConn { static {try { Class.forName(\"com.mysql.jdbc.Driver\"); } catch (Exception ex) { ex.printStackTrace();}} public static Connection getConn() { try { String url = \"jdbc:mysql://localhost:3306/apsfc\"; Properties inf = new Properties(); inf.setProperty(\"user\", \"root\"); inf.setProperty(\"password\", \"123456\"); inf.setProperty(\"useUnicode\", \"true\"); inf.setProperty(\"characterEncoding\", \"UTF-8\"); Connection conn = DriverManager.getConnection(url, inf); conn=DriverManager.getConnection(\"jdbc:mysql://localhost/apsfc?useUnicode=true&characterEncoding=gb2312\",\"root\",\"123456\"); return conn; } catch (Exception ex) { ex.printStackTrace(); return null;}} /** * * @param conn * @param st * @param rs * @Description 关闭数据库 */ public static void close(Connection conn, Statement st, ResultSet rs) { if (rs != null) { try { rs.close(); } catch (SQLException ex) { } } if (st != null) { try { st.close(); } catch (Exception ex) {}} if (conn != null) { try { conn.close(); } catch (Exception ex) { }}} public static void close(Connection conn, PreparedStatement pst, ResultSet rs) { if (rs != null) { try { rs.close(); } catch (SQLException ex) {}} if (pst != null) { try { pst.close(); } catch (Exception ex) { } } if (conn != null) { try { conn.close(); } catch (Exception ex) {}}}
5.1.2 订单模块数据库操作
public class OrderDao { private Connection conn = null; private Statement st = null; private ResultSet rs = null; private int totalpage = 0; private int currentpage = 0; public int getTotalpage() { return totalpage; } public int getCurrentpage() { return currentpage; } public List pageList(int page, int size) { List orderlist = new ArrayList(); String sql = \"SELECT COUNT(*) FROM orders\"; conn = DBConn.getConn(); try { st = conn.createStatement(); rs = st.executeQuery(sql); int totalcount = 0; if (rs.next()) { totalcount = rs.getInt(1); } if (totalcount != 0) { //totalpage = totalcount / size + 1; if (totalcount % size == 0) { totalpage = totalcount / size; } else { totalpage = totalcount / size + 1; } int pagesize = 0; currentpage = page; if (page totalpage) { currentpage = totalpage;} if (currentpage == totalpage&&totalcount % size != 0) { pagesize = totalcount % size; } else { pagesize = size;} int start = (currentpage - 1) * size; sql = \"select c.id as id,a.id as userid,b.id as menuid,c.id as orderid,realname,phone,address,b.name as menuname,menusum,price1,times,delivery from users a,menus b,orders c where a.id=c.userid and b.id=c.menuid limit \" + start + \",\" + pagesize; st = conn.createStatement(); rs = st.executeQuery(sql); while (rs.next()) { Order order = new Order(); order.setId(Integer.parseInt(rs.getString(\"id\"))); order.setUserid(Integer.parseInt(rs.getString(\"userid\"))); order.setMenuid(Integer.parseInt(rs.getString(\"menuid\"))); order.setOrderid(Integer.parseInt(rs.getString(\"orderid\"))); order.setRealname(rs.getString(\"realname\")); order.setPhone(rs.getString(\"phone\")); order.setAddress(rs.getString(\"address\")); order.setMenuname(rs.getString(\"menuname\")); order.setMenusum(Integer.parseInt(rs.getString(\"menusum\"))); order.setPrice1(Float.parseFloat(rs.getString(\"price1\"))); order.setTimes(rs.getString(\"times\")); order.setDelivery(Integer.parseInt(rs.getString(\"delivery\"))); orderlist.add(order);}} } catch (SQLException e) { e.printStackTrace(); } finally { DBConn.close(conn, st, rs);} return orderlist; } public List getOrderByDate(String date) { List orderlist = new ArrayList(); conn = DBConn.getConn(); try { String sql = \"select c.id as id,a.id as userid,b.id as menuid,c.id as orderid,realname,phone,address,b.name as menuname,menusum,price1,times,delivery from users a,menus b,orders c where a.id=c.userid and b.id=c.menuid and c.times like \'%\" + date + \"%\'\"; st = conn.createStatement(); rs = st.executeQuery(sql); while (rs.next()) { Order order = new Order(); order.setId(Integer.parseInt(rs.getString(\"id\"))); order.setUserid(Integer.parseInt(rs.getString(\"userid\"))) order.setMenuid(Integer.parseInt(rs.getString(\"menuid\")));order.setOrderid(Integer.parseInt(rs.getString(\"orderid\")));order.setRealname(rs.getString(\"realname\"));order.setPhone(rs.getString(\"phone\"));order.setAddress(rs.getString(\"address\"));order.setMenuname(rs.getString(\"menuname\"));order.setMenusum(Integer.parseInt(rs.getString(\"menusum\")));order.setPrice1(Float.parseFloat(rs.getString(\"price1\")));order.setTimes(rs.getString(\"times\"));order.setDelivery(Integer.parseInt(rs.getString(\"delivery\")));orderlist.add(order);}} catch (SQLException e) {e.printStackTrace();} finally {DBConn.close(conn, st, rs);}return orderlist;}public List getOrderByMenuname(String menuname) {List orderlist = new ArrayList();conn = DBConn.getConn();try {String sql = \"select c.id as id,a.id as userid,b.id as menuid,c.id as orderid,realname,phone,address,b.name as menuname,menusum,price1,times,delivery from users a,menus b,orders c where a.id=c.userid and b.id=c.menuid and b.name like \'%\"+ menuname + \"%\'\";st = conn.createStatement();rs = st.executeQuery(sql);while (rs.next()) {Order order = new Order();order.setId(Integer.parseInt(rs.getString(\"id\")));order.setUserid(Integer.parseInt(rs.getString(\"userid\")));order.setMenuid(Integer.parseInt(rs.getString(\"menuid\")));order.setOrderid(Integer.parseInt(rs.getString(\"orderid\")));order.setRealname(rs.getString(\"realname\"));order.setPhone(rs.getString(\"phone\"));order.setAddress(rs.getString(\"address\"));order.setMenuname(rs.getString(\"menuname\"));order.setMenusum(Integer.parseInt(rs.getString(\"menusum\")));order.setPrice1(Float.parseFloat(rs.getString(\"price1\")));order.setTimes(rs.getString(\"times\"));order.setDelivery(Integer.parseInt(rs.getString(\"delivery\")));orderlist.add(order);}} catch (SQLException e) {e.printStackTrace();} finally {DBConn.close(conn, st, rs);}return orderlist;}public List getOrderByUserid(int userid) {List orderlist = new ArrayList();conn = DBConn.getConn();try {String sql = \"select c.id as id,a.id as userid,b.id as menuid,c.id as orderid,realname,phone,address,b.name as menuname,menusum,price1,times,delivery from users a,menus b,orders c where a.id=c.userid and b.id=c.menuid and c.userid=\"+ userid;st = conn.createStatement();rs = st.executeQuery(sql);while (rs.next()) {Order order = new Order();order.setId(Integer.parseInt(rs.getString(\"id\")));order.setUserid(Integer.parseInt(rs.getString(\"userid\")));order.setMenuid(Integer.parseInt(rs.getString(\"menuid\")));order.setOrderid(Integer.parseInt(rs.getString(\"orderid\")));order.setRealname(rs.getString(\"realname\"));order.setPhone(rs.getString(\"phone\"));order.setAddress(rs.getString(\"address\"));order.setMenuname(rs.getString(\"menuname\"));order.setMenusum(Integer.parseInt(rs.getString(\"menusum\")));order.setPrice1(Float.parseFloat(rs.getString(\"price1\")));order.setTimes(rs.getString(\"times\"));order.setDelivery(Integer.parseInt(rs.getString(\"delivery\")));orderlist.add(order);}} catch (SQLException e) {e.printStackTrace();} finally {DBConn.close(conn, st, rs);}return orderlist;}public int update(int id) {String sql = \"\";sql = \"update orders set delivery=1 where id=\" + id;int temp = 0;conn = DBConn.getConn();try {st = conn.createStatement();temp = st.executeUpdate(sql);} catch (SQLException e) {e.printStackTrace();temp = -1;} finally {DBConn.close(conn, st, rs);}return temp;}public int add(Order order) {String sql = \"\";sql = \"insert into orders(userid,menuid,menusum,times,delivery)\"+ \" values(\" + order.getUserid() + \",\" + order.getMenuid()+ \",\" + order.getMenusum() + \",\'\" + order.getTimes() + \"\',\"+ order.getDelivery() + \")\";int temp = 0;conn = DBConn.getConn();try {st = conn.createStatement();temp = st.executeUpdate(sql);} catch (SQLException e) {e.printStackTrace();temp = -1;} finally {DBConn.close(conn, st, rs);}return temp;}public int delete(int id) {String sql = \"\";sql = \"delete from orders where id=\" + id;int temp = 0;conn = DBConn.getConn();try {st = conn.createStatement();temp = st.executeUpdate(sql);} catch (SQLException e) {e.printStackTrace();temp = -1;} finally {DBConn.close(conn, st, rs);}return temp;}public List getOrderByDate(int userid,String date) {List orderlist = new ArrayList();conn = DBConn.getConn();try {String sql = \"select c.id as id,a.id as userid,b.id as menuid,c.id as orderid,realname,phone,address,b.name as menuname,menusum,price1,times,delivery from users a,menus b,orders c where a.id=c.userid and b.id=c.menuid and c.times like \'%\"+ date + \"%\' and c.userid=\"+userid;st = conn.createStatement();rs = st.executeQuery(sql);while (rs.next()) {Order order = new Order();order.setId(Integer.parseInt(rs.getString(\"id\")));order.setUserid(Integer.parseInt(rs.getString(\"userid\")));order.setMenuid(Integer.parseInt(rs.getString(\"menuid\")));order.setOrderid(Integer.parseInt(rs.getString(\"orderid\")));order.setRealname(rs.getString(\"realname\"));order.setPhone(rs.getString(\"phone\"));order.setAddress(rs.getString(\"address\"));order.setMenuname(rs.getString(\"menuname\"));order.setMenusum(Integer.parseInt(rs.getString(\"menusum\")));order.setPrice1(Float.parseFloat(rs.getString(\"price1\")));order.setTimes(rs.getString(\"times\"));order.setDelivery(Integer.parseInt(rs.getString(\"delivery\")));orderlist.add(order);}} catch (SQLException e) {e.printStackTrace();} finally {DBConn.close(conn, st, rs);}return orderlist;}public List getOrderByMenuname(int userid,String menuname) {List orderlist = new ArrayList();conn = DBConn.getConn();try {String sql = \"select c.id as id,a.id as userid,b.id as menuid,c.id as orderid,realname,phone,address,b.name as menuname,menusum,price1,times,delivery from users a,menus b,orders c where a.id=c.userid and b.id=c.menuid and b.name like \'%\"+ menuname +\"%\' and c.userid=\"+userid;st = conn.createStatement();rs = st.executeQuery(sql);while (rs.next()) {Order order = new Order();order.setId(Integer.parseInt(rs.getString(\"id\")));order.setUserid(Integer.parseInt(rs.getString(\"userid\"))):order.setMenuid(Integer.parseInt(rs.getString(\"menuid\")));order.setOrderid(Integer.parseInt(rs.getString(\"orderid\")));order.setRealname(rs.getString(\"realname\"));order.setPhone(rs.getString(\"phone\"));order.setAddress(rs.getString(\"address\"));order.setMenuname(rs.getString(\"menuname\"));order.setMenusum(Integer.parseInt(rs.getString(\"menusum\")));order.setPrice1(Float.parseFloat(rs.getString(\"price1\")));order.setTimes(rs.getString(\"times\"));order.setDelivery(Integer.parseInt(rs.getString(\"delivery\")));orderlist.add(order);}} catch (SQLException e) {e.printStackTrace();} finally {DBConn.close(conn, st, rs);}return orderlist;}public List getOrderByDelivery(int userid,int delivery) {List orderlist = new ArrayList();conn = DBConn.getConn();try {String sql = \"select c.id as id,a.id as userid,b.id as menuid,c.id as orderid,realname,phone,address,b.name as menuname,menusum,price1,times,delivery from users a,menus b,orders c where a.id=c.userid and b.id=c.menuid and c.userid=\"+ userid+\" and delivery=\"+delivery;st = conn.createStatement();rs = st.executeQuery(sql);while (rs.next()) {Order order = new Order();order.setId(Integer.parseInt(rs.getString(\"id\")));order.setUserid(Integer.parseInt(rs.getString(\"userid\")));order.setMenuid(Integer.parseInt(rs.getString(\"menuid\")));order.setOrderid(Integer.parseInt(rs.getString(\"orderid\")));order.setRealname(rs.getString(\"realname\"));order.setPhone(rs.getString(\"phone\"));order.setAddress(rs.getString(\"address\"));order.setMenuname(rs.getString(\"menuname\"));order.setMenusum(Integer.parseInt(rs.getString(\"menusum\")));order.setPrice1(Float.parseFloat(rs.getString(\"price1\")));order.setTimes(rs.getString(\"times\"));order.setDelivery(Integer.parseInt(rs.getString(\"delivery\")));orderlist.add(order);}} catch (SQLException e) {e.printStackTrace();} finally {DBConn.close(conn, st, rs);}return orderlist;}}
5.2 订单模块创建
package com.apsfc.po;public class Order { private int id; private int userid; private int menuid; private int orderid; private String realname; private String phone; private String address; private String menuname; private int menusum; private float price1; private String times; private int delivery; public int getId() { return id;} public void setId(int id) { this.id = id;} public int getUserid() { return userid;} public void setUserid(int userid) { this.userid = userid;} public int getMenuid() { return menuid;} public void setMenuid(int menuid) { this.menuid = menuid;} public int getOrderid() { return orderid;} public void setOrderid(int orderid) { this.orderid = orderid;} public String getRealname() { return realname;} public void setRealname(String realname) { this.realname = realname; } public String getPhone() { return phone;} public void setPhone(String phone) { this.phone = phone;} public String getAddress() { return address;} public void setAddress(String address) { this.address = address;} public String getMenuname() { return menuname;} public void setMenuname(String menuname) { this.menuname = menuname;} public int getMenusum() { return menusum;} public void setMenusum(int menusum) { this.menusum = menusum;} public float getPrice1() { return price1;} public void setPrice1(float price1) { this.price1 = price1;} public String getTimes() { return times;} public void setTimes(String times) { this.times = times;} public int getDelivery() { return delivery;} public void setDelivery(int delivery) { this.delivery = delivery;}}
5.3 sevlet 事务处理
5.3.1 会员 servlet 事务处理
/** * Servlet implementation class UserOrderingServlet */@WebServlet(\"/UserOrderingServlet\")public class UserOrderingServlet extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public UserOrderingServlet() { super(); } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { /* * 解决乱码问题 */ request.setCharacterEncoding(\"utf-8\"); response.setContentType(\"text/html;charset=utf-8\"); response.setCharacterEncoding(\"utf-8\"); HttpSession session = request.getSession(); User user = (User) session.getAttribute(\"user\"); PrintWriter out = response.getWriter(); if (user != null) { SimpleDateFormat formatter = new SimpleDateFormat(\"yyyy-MM-dd HH:mm:ss\"); String date=formatter.format(new Date()); // 将日期时间格式化 List list =(List)session.getAttribute(\"shoppingcar\"); OrderDao odao=new OrderDao(); if (list != null) { for (int i = 0; i < list.size(); i++) { ShoppingCart sc = list.get(i); Order od=new Order(); od.setUserid(user.getId()); od.setMenuid(sc.getId()); od.setPrice1(sc.getPrice()); od.setMenusum(sc.getSums()); od.setTimes(date); od.setDelivery(0); odao.add(od);} session.removeAttribute(\"shoppingcar\"); out.write(\"alert(\'订单已提交,稍后将有客服给予确认并派送!\');window.navigate(\'./qiantai/index.jsp\');\"); return; }else{ out.write(\"alert(\'您的餐车是空的哦!快快去选购吧!\');window.navigate(\'./qiantai/index.jsp\');\");}} else { out.write(\"alert(\'对不起,请登录后再提交订单!\');window.navigate(\'./qiantai/login.jsp\');\"); return;}} /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { }}
5.3.2 管理员 sevlet 处理
package com.apsfc.servlet.admin;import java.io.IOException;import java.io.PrintWriter;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.Cookie;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpSession;import com.apsfc.dao.AdminDao;import com.apsfc.po.Admin;/** * Servlet implementation class AdminServlet */@WebServlet(\"/AdminServlet\")public class AdminServlet extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public AdminServlet() { super(); } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub Cookie[] ck=request.getCookies(); if (ck!=null){ for(int i=0 ;i<ck.length;i++){ if (ck[i].getName().equals(\"name\")){ ck[i].setMaxAge(0); response.addCookie(ck[i]); } if (ck[i].getName().equals(\"pwd\")){ ck[i].setMaxAge(0); response.addCookie(ck[i]); }}} HttpSession session = request.getSession(); session.removeAttribute(\"admin\"); PrintWriter out = response.getWriter(); out.write(\"top.location.href=\'./admin/index.jsp\'\"); } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding(\"utf-8\"); response.setContentType(\"text/html;charset=utf-8\"); PrintWriter out = response.getWriter(); int id = Integer.parseInt(request.getParameter(\"id\")); String name = request.getParameter(\"name\"); String pwd = request.getParameter(\"pwd\"); AdminDao adao=new AdminDao(); Admin ad =new Admin(); ad.setId(id); ad.setName(name); ad.setPwd(pwd); int flag = adao.update(ad); if (flag == -1) { out.write(\"alert(\'更新信息失败!\');window.navigate(\'./admin/admin_update.jsp\');\"); } else { HttpSession session = request.getSession(); session.removeAttribute(\"admin\"); session.setAttribute(\"admin\", ad); out.write(\"alert(\'更新信息成功!\');window.navigate(\'./admin/menus.jsp\');\");}}}
package com.apsfc.servlet.admin.order;import java.io.IOException;import java.text.SimpleDateFormat;import java.util.Date;import java.util.List;import java.util.Locale;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpSession;import com.apsfc.dao.OrderDao;import com.apsfc.po.Order;/** * Servlet implementation class OrderServlet */@WebServlet(\"/OrderServlet\")public class OrderServlet extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public OrderServlet() { super(); // TODO Auto-generated constructor stub } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding(\"utf-8\"); response.setContentType(\"text/html;charset=utf-8\"); String id =request.getParameter(\"id\"); String reqtype = request.getParameter(\"reqtype\"); String url=\"\"; OrderDao od=new OrderDao(); if(reqtype.equals(\"delivery\")){ od.update(Integer.parseInt(id)); url=\"./admin/order.jsp\"; response.sendRedirect(url); } if(reqtype.equals(\"del\")){ od.delete(Integer.parseInt(id)); url=\"./admin/order.jsp\"; response.sendRedirect(url); } if(reqtype.equals(\"statistic\")){ SimpleDateFormat formatter = new SimpleDateFormat (\"yyyy-MM-dd kk:mm\",Locale.getDefault()); String currentdate = formatter.format(new Date()); currentdate=currentdate.substring(0, 10); List list=null; list=od.getOrderByDate(currentdate); HttpSession session = request.getSession(); session.setAttribute(\"orderstatistic\", list); url=\"./admin/order_statistic.jsp\"; response.sendRedirect(url); } } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub request.setCharacterEncoding(\"utf-8\"); response.setContentType(\"text/html;charset=utf-8\"); //PrintWriter out = response.getWriter(); String userid = request.getParameter(\"userid\"); String menuname =request.getParameter(\"menuname\"); String date = request.getParameter(\"date\"); OrderDao od=new OrderDao(); List list=null; if(userid != null && !userid.equals(\"\")){ list=od.getOrderByUserid(Integer.parseInt(userid)); } if(menuname != null && !menuname.equals(\"\")){ list=od.getOrderByMenuname(menuname); }if(date != null && !date.equals(\"\")) list=od.getOrderByDate(date); } HttpSession session = request.getSession(); session.setAttribute(\"ordersearch\", list);response.sendRedirect(\"./admin/order_search.jsp\");}}
5.4 前台设计
5.4.1 管理员订单管理界面设计

订单信息

销售订单查询结果信息列表 用户ID 真实姓名 联系方式 家庭住址 菜品名称 订购数量 单价(元) 合计(元) 订购时间 是否派送 确认订单 <% int currentpage=1; String str=(String)request.getParameter(\"currentpage\"); if(str!=null&&str!=\"\"){ currentpage=Integer.parseInt(str); } OrderDao od=new OrderDao(); List list=od.pageList(currentpage,5); for(int i=0;i <ahref=\"../OrderServlet?id=&reqtype=delivery\">确认 <ahref=\"../OrderServlet?id=&reqtype=del\">取消 第页 共页 [首页] <a href=\"?currentpage=\">[尾页] <a href=\"?currentpage=\">[上一页]<a href=\"?currentpage=\">[下一页]

订单查询

按用户ID查询 按菜品名称查询 按销售日期查询
销售订单查询结果信息列表 用户ID 真实姓名 联系方式 家庭住址 菜品名称 订购数量 单价(元) 合计(元) 订购时间 是否派送 <% List list=(List)session.getAttribute(\"ordersearch\"); if (list!=null){ for(int i=0;i

类别信息

本日销售额统计 菜品名称 订购数量 单价 合计 <%List list=(List)session.getAttribute(\"orderstatistic\"); if (list!=null){ float sum=0.0f; for(int i=0;i 元 本日销售总额:元
6 调试分析
6.1 测试数据分析
给出以下用户信息进行相应的测试,如表 6 所示。
id
name
pwd
realname
sex
age
card
address
phone
code
type
2
222
222
2221
女
241
211111111111111111
郑州市高新区
13988888888
123@163.commailto:123@163.com
110044
0
3
sunday
123
张三
男
26
4222222222222222
郑州市高新区
13901001111
13901001111@139.commailto:13901001111@139.com
101000
0
4
1
1
李二狗
男
1
1
郑州市高新区
1
1
1
0
8
炸支付
4565
赵志国
男
45
410621199709284517
郑州市高新区
13253312194
456250@111.commailto:456250@111.com
45445
0
9
evan
888333
王权
男
56
456464546545654
郑州市高新区
2343434
45654545@qq.commailto:45654545@qq.com
456250
0
10
fas
fa
fasd
男
12
324254345345
郑州市高新区
13121555
32433@adsfsmailto:32433@adsfs
4533
0
表 6 用户信息表测试数据
给出以下管理员信息测试数据以测试表的完整性约束等,如下表 7 所示。
id
name
pwd
authority
1
sa
sa
0
2
admin
admin
0
3
张三
3
0
4
sas
1
0
表 7 管理员信息表
给出以下菜品信息测试数据对数据库进行测试。
id
name
1
凉拌菜
2
炒菜
6
炒饭
10
蒸菜
11
川菜
12
鲁菜
表 8 菜品类别表
给出以下菜品信息表进行测试分析,如下表 9 所示。
id
name
typeid
burden
brief
price
sums
price1
sums1
imgpath
12
粉蒸肉
10
米粉、五花肉
暂无
26.00
0
23.00
0
img/m_fenzhengrou.gif
14
糖醋排骨
2
排骨、糖、醋
暂无
26.00
0
24.00
4
img/m_tangcupaigu.gif
15
咸肉菜饭
1
咸肉、米饭
暂无
15.00
0
12.00
4
img/m_xianroucaifan.gif
17
五香驴肉
1
驴肉
暂无
25.00
0
21.00
1
img/m_wuxianglvrou.gif
18
黄瓜拉皮
1
黄瓜、拉皮
暂无
8.00
0
6.00
1
img/m_huanggualapi.gif
19
水煮鱼
11
鱼,辣椒
暂无
38.00
0
32.00
1
img/m_shuizhuyu.gif
表 9 菜品信息表数据
给出以下订单信息表测试数据进行调试分析,如下表 10 所示:
id
userid
menuid
menusum
times
delivery
16
2
12
2
2018-01-07 13:16:28
1
17
1
14
1
2018-01-07 13:23:30
1
19
4
15
2
2018-01-07 23:26:20
1
23
4
14
1
2015-01-07 00:35:09
1
24
4
17
1
2018-01-07 00:35:09
1
25
2
15
1
2018-01-07 20:14:23
1
27
2
18
1
2018-01-07 20:31:56
1
28
2
19
1
2018-01-07 20:31:56
0
29
4
15
1
2018-01-05 19:16:00
0
30
4
14
1
2018-01-08 17:38:50
0
31
4
15
1
2018-01-09 10:35:36
0
表 10 订单信息表数据
6.2 模块问题分析
序号
存在问题
解决方案
备注
1
插入数据库中文出现乱码
将数据库中表面默认编码设置为 utf-8
已解决
2
在页面中返回数据时出现中文乱码
在 JSP、servlet 处理中设置编码格式为 utf-8
已解决
3
添加订单信息时数据库报错
触发器限制了进行插入,修改或删除该触发器
已解决
4
表结构中有些字段需要限制取值范围
使用触发器,限制用户行为,前端限制用户输入
仅对个别问题进行了限制
5
按照菜品进行订单查询,用户输入有时会想不起来,需要改进
使用模糊查询的方式,更好的增强了用户体验
已解决
表 11 问题及改进策略
7 测试结果
7.1 测试数据表
id
name
pwd
authority
4
sas
1
0
表 12 管理员数据信息测试用例
id
name
pwd
realname
sex
age
card
address
phone
code
type
4
1
1
李二狗
男
1
1
郑州市高新区
1
1
1
0
表 13 用户数据测试用例
7.2 订单模块用户界面测试
用 id 为 1 的用户账号进行登录,用户选完订单进入购物车,然后点击提交按钮。程序运行结果如图 8 所示:
图 8 用户进行点餐
用户进入我的订单详情页面,程序运行结果如图 9 所示:
图 9 用户进入订单页面
用户查询该用户的所有订单,程序运行结果如图 10 所示:
图 10 用户查询所有订单
查询我的所有未派送订单,程序运行结果如图 11 所示:
图 11 查询未派送订单
查询已经派送的订单,程序运行结果如图 12 所示:
图 12 查询已派送的订单
按照菜品名称查询订单,程序运行结果如图 13 所示:
图 13 按照菜品名称查询
按照销售日期查询订单,程序运行结果如图 14 所示:
图 14 按照销售日期查询
7.3 管理员订单管理模块
使用管理员身份登录后台管理系统,进入订单管理模块,查看全部订单相关信息。程序运行结果如图 15 所示:
图 15 显示订单所有信息
销售订单查询,程序运行结果如图 16 所示:
图 16 按照销售订单查询
管理员按照用户 ID 进行查询,程序运行结果如图 17 所示:
图 17 按照用户 ID 查询
管理员按照菜品名称进行查询,程序运行结果如图 18 所示:
图 18 按照菜品名称查询
管理员按照销售日期进行查询,程序运行结果如图 19 所示:
图 19 按照销售日期查询
管理员统计今日销售订单,程序运行结果如图 20 所示:
图 20 统计今日销售额
8 参考文献
[1] 钱雪忠.数据库原理及应用[M].北京:邮电大学出版社.2007.8
[2] 孙家广.软件工程[M].北京:高等教育出版社.2005.7
[3] 戴小平.数据库系统及应用[M].北京:中国科学技术出版社
[4] 李明欣.基于 BootStrap3 的 JSP 项目实例教程[M].北京:航空航天大学出版社
[5] 赵洛育.html CSS JavaScript 网页设计与制作从入门到精通[M].北京:清华大学出版社
[6] 陈晓勇.MySQL DBA 修炼之道[M].北京:机械工业出版社.2017.1
[7] 刘增杰.MySQL 5.6 从入门到精通[M].北京:清华大学出版社.2016.9