吃货联盟订单系统
写在前面:
10月份老师将这个任务交给我,但是因为期间一直有事,没有心思搞这个,就一直耽误了。
原本的项目要求并没有数据库部分,但是本人感觉单独只写java方面程序没有意思,就自己改了一下。
这个项目是本人第一个实战项目,也是第一次接触JDBC。
利用课余时间(共计约10小时)复习了Mysql数据库,通过B站学会了连接数据库操作,
在文心一言的帮助下完成了该项目。
项目还有很多地方需要优化,但本人专业并不很依赖JAVA,所以也无心继续花费时间改善
在这里指出一下未完善的小bug
1.因为使用控制台输出,导致输出长度不一时,输出内容杂乱
2.我要订餐:这里应该在订餐之前打印所有菜品,同时兼容使用菜品ID订餐
3.订餐时间固定为当前时间,无法实现预订功能
4.仅在查询指定订单时才会自动更新订单状态
下面是代码实现:
Main:
/*
* 项目名称:吃货联盟订单系统
* 物联网程序猿:珂是王可珂
* 项目开始时间: 2023-12-14
*/
import java.sql.SQLException;
public class Main {
static Print print = new Print();
public static void main(String[] args) throws SQLException, ClassNotFoundException {
SQL_System.connect_sql(); // 初始化连接数据库
print.menu(); // 进入系统
SQL_System.close_sql(); // 释放空间
}
}
Print:
在这里主要实现了循环菜单打印和一个选择函数
import java.sql.SQLException;
import java.util.Scanner;
public class Print {
Scanner sc = new Scanner(System.in);
Food_Systm food_systm = new Food_Systm();
/**
* 函数功能: 主菜单打印
*/
public void menu() throws SQLException {
String xz ;
boolean flag = true ;
System.out.println("\n欢迎进入吃货联盟订单系统!");
do {
System.out.println("\n");
System.out.println("主菜单: ");
System.out.println("\t1. 我要订餐");
System.out.println("\t2. 查看餐袋");
System.out.println("\t3. 订单查询");
System.out.println("\t4. 删除订单");
System.out.println("\t5. 我要点评");
System.out.println("\t6. 订单记录");
System.out.println("\t7. 退出系统");
System.out.print("请选择:");
xz = sc.next();
if (!xz.isEmpty()) { // xz不为空进入判断
try {
switch (xz) {
case "1":
System.out.println("\t欢迎进入订餐页面");
food_systm.Order_food();
break;
case "2":
System.out.println("\t欢迎进入你的餐袋");
food_systm.Show_Meal_bags();
break;
case "3":
System.out.println("\t欢迎进入订单查询页面");
food_systm.Order_status();
break;
case "4":
System.out.println("\t欢迎进入删除订单页面");
food_systm.Delete_order();
break;
case "5":
System.out.println("\t欢迎进入我要点评页面");
food_systm.Comments();
break;
case "6":
System.out.println("\t欢迎进入订单记录页面");
food_systm.Historical_orders();
break;
case "7":
System.out.println("退出系统!");
flag =false;
break;
default:
System.out.println("输入错误!请重新输入");
break;
}
} catch (Exception e) {
System.out.println("\n报错啦");
}
}
}while (flag) ;
}
/**
* 函数功能: 选择(y/n)
* 传参: 无
* 返回: y 确认
* n 取消
*/
public String xz(){
boolean flag ; //循环标志位
String xz ;
do {
flag =false;
xz=sc.next();
if(xz.equals("y")){
return xz;
}else if(xz.equals("n")){
return xz;
}else {
System.out.println("输入错误!请重新输入");
flag=true;
}
}while (flag);
return xz;
}
}
SQL_System:
在这里实现了连接数据库与释放资源
/*
* 连接数据库
* 时间 : 2023-12-15
*/
import java.sql.*;
public class SQL_System {
static Connection connection;
static Statement statement;
static ResultSet resultSet;
/**
* 函数功能: 连接数据库
* @throws ClassNotFoundException
* @throws SQLException
*/
public static void connect_sql() throws ClassNotFoundException, SQLException {
long start = System.currentTimeMillis(); //开始计时
//注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//连接数据库
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/order_food", "root", "123456");
//获取执行对象
statement = connection.createStatement();
long end = System.currentTimeMillis(); //结束计时
if(connection != null) {
System.out.println(connection);
System.out.println("登入系统成功,耗时: " + (end - start) + "ms");
}else{
System.out.println("连接失败,请重新进入系统!");
}
//查询测试
// String sql = "SELECT * FROM orderer_info";
// statement.executeQuery(sql);
}
/**
* 函数功能: 释放资源
*/
public static void close_sql() throws SQLException {
if(resultSet != null) {
resultSet.close();
} else if (statement != null) {
statement.close();
} else if (connection != null) {
connection.close();
}
}
}
Food_Systm:
这里实现了菜单栏里的各级任务
/*
* 订单系统主要函数
*/
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Scanner;
public class Food_Systm extends SQL_System {
static Print print = new Print();
Scanner sc = new Scanner(System.in);
String sql ; // 存储SQL语句
/**
* 函数功能: 新建订餐
*/
public void Order_food () throws SQLException {
// LocalDateTime dateTime = LocalDateTime.now(); //获取当前时间
// 以特定格式打印日期和时间
// DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
int Dishes_id; //菜品ID
System.out.print("请输入订单ID:");
int ID = sc.nextInt();
System.out.print("请输入要下单的菜品:");
String Dishes = sc.next();
Dishes_id=get_Dishes_id(Dishes); //获取菜品ID
//菜品存在才继续操作
if (Dishes_id != 0){
System.out.print("请输入您的姓名:");
String name = sc.next();
System.out.print("请输入您的订餐数量:");
int number = sc.nextInt();
//获取当前时间
LocalDateTime currentDateTime = LocalDateTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String time = currentDateTime.format(formatter);
System.out.println("当前日期和时间: " + time);
System.out.print("请输入您的送餐地址:");
String address = sc.next();
System.out.println("开始插入!");
try {
sql = "INSERT INTO orderer_info VALUES (?,?,?,?,default,?,0);";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setInt(1, ID); //订单ID
preparedStatement.setInt(2, Dishes_id); //菜品ID
preparedStatement.setString(3, name); //姓名
preparedStatement.setInt(4, number); //订餐数量
preparedStatement.setString(5, address); //送餐地址
preparedStatement.executeUpdate();
System.out.println("插入成功!");
} catch (SQLException e) {
System.out.println("插入错误!");
throw new RuntimeException(e);
}
}else {
System.out.println("抱歉,小店没有该菜品");
}
close_sql(); //清理资源
}
/**
* 获取点的菜品的ID
* 传参: 菜品名称
*/
public int get_Dishes_id(String dishes) throws SQLException {
int Dishes_id;
sql = "select dis.Dishes_id 菜品ID, dis.Dishes_name 菜品名称, dis.amount 菜品金额, dis.Praise 点赞数量\n" +
"from Dishes dis\n" +
"where dis.Dishes_name = ?;";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1, dishes);
resultSet = preparedStatement.executeQuery();
if(resultSet != null && resultSet.next()){
Dishes_id = resultSet.getInt("菜品ID"); // 从结果集中获取菜品ID
System.out.println("菜品ID:" + Dishes_id);
} else {
Dishes_id = 0; // 如果没有找到,返回0
}
return Dishes_id;
}
/**
* 函数功能: 查看指定ID餐袋
*/
public void Show_Meal_bags() throws SQLException {
int index =0; //记录查询到的数据条数
System.out.print("请输入您的订单编号:");
int next_id = sc.nextInt();
sql = "select ord.id 订单ID , ord.Dishes_id 菜品ID, ord.`name` 订餐人姓名,ord.number 订餐数量,\n" +
" ord.times 订餐时间, ord.addresses 送餐地址,dis.Dishes_name 菜品名称\n" +
"FROM Orderer_info ord\n" +
" INNER JOIN Dishes dis\n" +
" on ord.Dishes_id = dis.Dishes_id\n" +
"where ord.id =?;";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
// 传参 : 1 表示第一个占位符 comments 表示点评操作
preparedStatement.setInt(1, next_id);
resultSet =preparedStatement.executeQuery();
try {
if (resultSet!=null) {
System.out.println("订单ID 订餐人姓名 订餐数量 订餐时间 送餐地址 菜品名称");
while (resultSet.next()) {
System.out.print(" " + resultSet.getString("订单ID") + "\t");
System.out.print("\t" + resultSet.getString("订餐人姓名") + "\t");
System.out.print(" " + resultSet.getString("订餐数量") + "\t ");
System.out.print(resultSet.getString("订餐时间") + "\t");
System.out.print(resultSet.getString("送餐地址") + "\t");
System.out.print(resultSet.getString("菜品名称") + "\t");
System.out.println();
index++;
}
} else {
System.out.println("查询失败!");
}
if (index == 0) {
System.out.println("未查询到任何数据");
}
} catch (SQLException e) {
System.out.println("打印失败");
}
System.out.println("总金额: "+select_money(next_id) +" 元" ); //打印总金额
close_sql(); // 释放空间
}
/**
* 函数功能: 查询订单状态
*/
public void Order_status() throws SQLException {
int flag; //订单状态标志 1为已送达 0为未送达
String xz; //选择是否需要修改订单状态
System.out.print("请输入您的订单编号:");
int next_id = sc.nextInt(); //订单ID
automatic_Update_status(next_id); //自动修改订单状态
sql = "select ord.id 订单ID,ord.times 订餐时间,ord.states 订单状态" +
" from Orderer_info ord where ord.id =?;";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setInt(1, next_id);
resultSet = preparedStatement.executeQuery();
try {
if (resultSet!= null) {
// 自动判断订单状态
while (resultSet.next()) {
flag=resultSet.getInt("订单状态");
if(flag == 1){
System.out.println("已送达");
}else {
System.out.println("未送达");
}
}
}
System.out.println("是否需要修改订单状态? y/n");
xz=print.xz();
if(xz .equals("y")){
Update_status(next_id);
return;
} else if (xz.equals("n")) {
System.out.println("退出系统");
return;
}
} catch (SQLException e) {
System.out.println("查询失败");
throw new RuntimeException(e);
}
close_sql(); //清理内存
}
/**
* 函数功能: 修改订单状态
*/
public String Update_status(int id) throws SQLException {
String xz; //订单是否送达
System.out.println("订单是否送达? y/n");
xz=print.xz();
if(xz.equals("y")){
sql = "UPDATE Orderer_info ord\n" +
"SET ord.states = 1\n" +
"WHERE ord.id = ?;";
}else if(xz.equals("n")){
sql = "UPDATE Orderer_info ord\n" +
"SET ord.states = 0\n" +
"WHERE ord.id = ?;";
}
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setInt(1, id);
if(preparedStatement.executeUpdate() >= 1){
System.out.println("修改成功!");
}else {
System.out.println("修改失败!");
}
return xz;
}
/**
* 函数功能: 自动修改订单状态
* 传参: 需要修改状态的订单ID
*/
public void automatic_Update_status(int id) throws SQLException {
sql = "UPDATE Orderer_info ord\n" +
"SET ord.states = 1\n" +
"WHERE TIMESTAMPDIFF(MINUTE, ord.times, NOW()) > 20 AND ord.id = ?;";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setInt(1, id);
// if(preparedStatement.executeUpdate() >= 1){
// System.out.println("修改成功!");
// }else {
// System.out.println("修改失败!");
// }
}
/**
* 函数功能: 点评菜品
*/
public void Comments() throws SQLException {
//sql语句
sql="select dis.Dishes_id 菜品ID, dis.amount 菜品金额,\n" +
"dis.Praise 点赞数量 , dis.Dishes_name 菜品名称 from dishes dis";
System.out.println("菜品ID 菜品金额 点赞数量 菜品名称"); //表头
try {
resultSet = statement.executeQuery(sql);
while (resultSet.next()) {
System.out.print(" " + resultSet.getString(1) + "\t");
System.out.print("\t" +resultSet.getString(2) + "\t");
System.out.print(" " +resultSet.getString(3) + "\t " );
System.out.print(resultSet.getString(4) + "\t");
System.out.println();
}
} catch (SQLException e) {
System.out.println("查询失败");
e.printStackTrace();
}
System.out.print("请输入要点评的菜品ID: ");
int id = sc.nextInt();
System.out.print("请输入点评操作: ");
int comments = sc.nextInt();
comments = Outofbounds_judgment(comments); //限制评分
sql = "UPDATE dishes SET Praise = Praise + ? WHERE Dishes_id = ?;"; // ? 表示占位符
// preparedStatement 执行前面定义的SQL更新语句 返回值被存储在变量 preparedStatement中
PreparedStatement preparedStatement = connection.prepareStatement(sql);
// 传参 : 1 表示第一个占位符 comments 表示点评操作
preparedStatement.setInt(1, comments);
// 传参 : 12 表示第一个占位符 comments 表示点评的菜品ID
preparedStatement.setInt(2, id);
// 返回被更新的行数
if(preparedStatement.executeUpdate() >= 1){
System.out.println("操作成功!");
}else {
System.out.println("操作失败!");
}
System.out.println("菜品ID 菜品金额 点赞数量 菜品名称");
try {
sql = "select dis.Dishes_id 菜品ID, dis.amount 菜品金额, +\n " +
" dis.Praise 点赞数量 , dis.Dishes_name 菜品名称 from dishes dis WHERE Dishes_id = ?;";
PreparedStatement preparedStatement2 = connection.prepareStatement(sql); //新建PreparedStatement,并且传入sql语句
preparedStatement2.setInt(1, id);
resultSet = preparedStatement2.executeQuery(); //将查询结果存储到 resultSet
while (resultSet.next()) {
System.out.print(" " + resultSet.getString("菜品ID") + "\t");
System.out.print("\t" +resultSet.getString("菜品金额") + "\t");
System.out.print(" " +resultSet.getString("点赞数量") + "\t " );
System.out.print(resultSet.getString("菜品名称") + "\t");
System.out.println();
}
} catch (SQLException e) {
System.out.println("查询失败");
e.printStackTrace();
}
close_sql(); // 释放空间
}
/**
* 函数功能 : 限制单次评分上下限
* @param comments 客户输入评分
* @return 返回限制后评分
*/
private int Outofbounds_judgment(int comments) {
if(comments > 5){
comments = 5;
System.out.println("超出单次评分上限! 操作更改为加5分");
} else if (comments < (-5)) {
comments = (-5) ;
System.out.println("超出单次评分下限! 操作更改为减5分");
}
return comments;
}
/**
* 函数功能: 查询历史订单
*/
public void Historical_orders() throws SQLException {
sql = "select ord.id 订单ID , ord.Dishes_id 菜品ID, ord.name 订餐人姓名,ord.number 订餐数量,\n" +
"ord.addresses 送餐地址,ord.times 订餐时间 ,dis.Dishes_name 菜品名称 from orderer_info ord\n" +
"INNER JOIN dishes dis\n" +
"on ord.Dishes_id = dis.Dishes_id\n";
System.out.println("订单ID 菜品ID 订餐人姓名 订餐数量 送餐地址 订餐时间 \t 菜品名称 ");
try {
resultSet = statement.executeQuery(sql); //查询并存储结果
while (resultSet.next()) {
System.out.print(" " + resultSet.getString("订单ID") + "\t");
System.out.print("\t" +resultSet.getString("菜品ID") + "\t");
System.out.print(" " +resultSet.getString("订餐人姓名") + "\t" + "\t");
System.out.print(resultSet.getString("订餐数量") + "\t");
System.out.print(" "+resultSet.getString("送餐地址") + "\t");
System.out.print(resultSet.getString("订餐时间") + "\t");
System.out.println(" "+resultSet.getString("菜品名称"));
}
} catch (SQLException e) {
System.out.println("查询失败");
e.printStackTrace();
}
close_sql(); // 释放空间
}
/**
* 函数功能: 删除指定ID订单
*/
public void Delete_order() throws SQLException {
String xz; //是否删除订单
int next_id; //操作的订单号
System.out.print("请输入需要删除的订单ID:");
next_id = sc.nextInt();
System.out.println("您确定删除吗? y/n");
xz = print.xz();
if(xz.equals("y")){
sql = "DELETE FROM Orderer_info WHERE id = ?;";
PreparedStatement preparedStatement = connection.prepareStatement(sql); //新建PreparedStatement,并且传入sql语句
preparedStatement.setInt(1, next_id);
if(preparedStatement.executeUpdate() >= 1) {
System.out.println("删除成功");
}else {
System.out.println("删除失败,请确认订单ID");
}
}else if(xz.equals("n")){
System.out.println("退出页面");
}
}
/**
* 函数功能: 查询订单总金额
* 传参: 需要查询的订单ID
*/
public float select_money(int id) throws SQLException {
sql ="select sum(dis.amount * ord.number ) 总金额\n" +
"from Orderer_info ord\n" +
"INNER JOIN Dishes dis\n" +
"on ord.Dishes_id = dis.Dishes_id\n" +
"where ord.id =?;";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setInt(1, id);
resultSet = preparedStatement.executeQuery();
if (resultSet.next()) {
return resultSet.getFloat("总金额");
}else {
return 0;
}
}
}
数据库:
这里是数据库表结构和测试用的sql语句
DROP DATABASE if EXISTS order_food; #删除数据库
show databases ;
CREATE DATABASE if not EXISTS order_food; #创建数据库
USE order_food; #使用该数据库
DROP TABLE if exists Orderer_info;
DROP TABLE if exists Dishes;
CREATE TABLE #创建订单人信息表
IF
NOT EXISTS Orderer_info (
id INT ( 5 ) NOT NULL COMMENT '订单ID',
Dishes_id INT ( 5 ) NOT NULL COMMENT '菜品ID',
`name` VARCHAR ( 20 ) NOT NULL COMMENT '订餐人姓名',
-- Dishes VARCHAR ( 50 ) NOT NULL COMMENT '菜品',
number INT ( 5 ) NOT NULL COMMENT '数量',
times DATETIME NOT NULL DEFAULT ( now( ) ) COMMENT '订餐时间',
addresses VARCHAR ( 50 ) NOT NULL COMMENT '送餐地址',
states INT ( 1 ) NOT NULL CHECK ( states = 1 OR states = 0 ) default(0) COMMENT '订单状态' # 0预定 1送达
) COMMENT = '订餐人信息表';
CREATE TABLE #创建菜品表
IF
NOT EXISTS Dishes (
Dishes_id INT ( 5 ) UNIQUE KEY NOT NULL PRIMARY KEY COMMENT '菜品ID',
Dishes_name VARCHAR ( 50 ) NOT NULL COMMENT '菜品名称',
amount DOUBLE ( 5, 2 ) NOT NULL COMMENT '菜品金额',
Praise int (5) NOT NULL COMMENT '点赞数量'
) COMMENT = '菜品表';
SHOW TABLES;
ALTER TABLE Orderer_info ADD CONSTRAINT FK_Dishes FOREIGN KEY ( Dishes_id ) REFERENCES Dishes ( Dishes_id );
insert into Dishes VALUES(1,'鱼香肉丝',38.38,200),
(2,'红烧肉',39.00,250),
(3,'小鸡炖蘑菇',58.38,250),
(4,'大刀肉',8.88,250),
(5,'红油面皮',10.88,250),
(6,'西红柿炒蛋',88.88,250);
insert into Orderer_info VALUES(1,1,'张无忌',2,now(),'湖南化工5B354',0),
(1,3,'张无忌',1,now(),'湖南化工5B354',0),
(2,3,'张三丰',2, now(),'湖南化工5B454',1),
(3,2,'梅超风',2,now() ,'湖南化工5B254',0),
(4,2,'奥特曼',2, now(),'湖南化工5B344',0),
(5,1,'路人甲',2, now(),'湖南化工5B154',0);
INSERT INTO orderer_info VALUES (6,2,'张四丰',1,'2020-01-01','湖南化工5B222', 0);
INSERT INTO orderer_info VALUES (6,2,'张五丰',1,default,'湖南化工5B222', 0);
select *from Orderer_info;
select *from Dishes;
#查询订单表中菜品ID为 00002的订单信息
select *from Orderer_info ord
INNER JOIN Dishes dis
on ord.Dishes_id = dis.Dishes_id
where ord.Dishes_id =00002;
select ord.id 订单ID , ord.Dishes_id 菜品ID, ord.`name` 订餐人姓名,ord.number 订餐数量,
ord.times 订餐时间, ord.addresses 送餐地址,dis.Dishes_name 菜品名称 from Orderer_info ord
INNER JOIN Dishes dis
on ord.Dishes_id = dis.Dishes_id
where ord.Dishes_id =00002;
#查询菜品表所有信息
select dis.Dishes_id 菜品ID, dis.Dishes_name 菜品名称, dis.amount 菜品金额,
dis.Praise 点赞数量 from Dishes dis;
#查询点赞信息
select dis.Dishes_id 菜品ID, dis.Dishes_name 菜品名称, dis.amount 菜品金额, dis.Praise 点赞数量
from Dishes dis
where dis.Praise > 0;
#查询指定ID订单
select ord.id 订单ID , ord.Dishes_id 菜品ID, ord.`name` 订餐人姓名,ord.number 订餐数量,
ord.times 订餐时间, ord.addresses 送餐地址,dis.Dishes_name 菜品名称
from Orderer_info ord
INNER JOIN Dishes dis
on ord.Dishes_id = dis.Dishes_id
where ord.id =1;
#查询指定订单ID总金额
select sum(dis.amount * ord.number ) 总金额
from Orderer_info ord
INNER JOIN Dishes dis
on ord.Dishes_id = dis.Dishes_id
where ord.id =1;
#获取(修改)指定订单的状态
UPDATE Orderer_info ord
SET ord.states = 1
WHERE TIMESTAMPDIFF(MINUTE, ord.times, NOW()) > 20 AND ord.id = 1;
#查询指定ID订餐时间
select ord.id 订单ID,ord.times 订餐时间,ord.states 订单状态 from Orderer_info ord where ord.id =1;
#删除指定ID订单
DELETE FROM Orderer_info WHERE id = 1;
#通过菜品查询菜品ID
select dis.Dishes_id 菜品ID, dis.Dishes_name 菜品名称, dis.amount 菜品金额, dis.Praise 点赞数量
from Dishes dis
where dis.Dishes_name = '鱼香肉丝';
开发日志:
开发日志
-- 作者: 珂是王可珂
-- 项目名称: 吃货联盟订单系统(JDBC)
/****************************************************/
2023 - 12 - 14
开发了系统菜单以及菜单之间的跳转
使用navicat建立了基础的关系表,并且测试了多表联查
/****************************************************/
2023 - 12 - 15
使用IDEA连接了Mysql数据库,并且移植成功昨天的SQL
优化了菜单选项
菜单栏新增历史订单
优化数据库表格,菜品表新增点赞数量列
将原版本的"我要点赞"更改为"我要点评" 可以实现对菜品的差评评分
初步实现点评页面功能
初步实现历史订单功能
/****************************************************/
2023 - 12 - 16
优化了代码注释
优化了"我要点评","历史订单"业务逻辑
修改"历史订单"为"订单记录"
修改"订单签收"为"订单查询"并实现
"订单查询"功能: 送餐时间距离查询时间20min以上订单自动签收,可以手动修改订单签收状态
初步实现"查看餐袋"功能
实现并优化"删除订单"功能
初步实现"我要订餐"功能
/****************************************************/
2023 - 12 - 17
开始看任务PPT完善功能
优化了代码注释
优化"我要点评"功能 限制了单次评分的上下限(-5 / +5);
优化"订单查询"功能
优化"我要订餐"功能
写在后面:
通过这个项目,我体会到了自身项目经验严重不足,虽然这个小项目写的稀巴烂,但是也确实是提升了自己。