满汉楼(餐厅系统)——纯JAVA后端项目

项目涉及知识点:MySQL数据库,JDBC连接,面向对象(oop)...


 在观看完韩顺平老师的满汉楼项目之后我也是动手跟着写了一下,顺便也是融入了自己的思考使得项目更加完善

1,账单显示时间问题

在写代码的时候就发现这个问题了,由于mysql5版本以上不支持Java的Date类型到数据库的Date类型,因此载Bill类中定义BillDate的时候可以使用LocalDateTime来定义就不会报错了。

2,新增能够重复点餐功能

自己新增多次点菜功能,其实就是一次while,continue循环来点多份菜品:
 

while (looping) {
            System.out.print("请输入点餐的菜品号(-1退出):");
            int orderMenuId = Utility.readInt();
            if (orderMenuId == -1) {
                System.out.println("============取消点餐============");
                return;
            }
            System.out.print("请输入点餐的菜品量(-1退出):");
            int orderNums = Utility.readInt();
            if (orderNums == -1) {
                System.out.println("============取消点餐============");
                return;
            }

            //验证餐桌号是否存在
            DiningTable diningTable = diningTableService.getDiningTableById(orderDiningTableId);
            if (diningTable == null) {
                System.out.println("============餐桌号不存在============");
                return;
            }
            //验证菜品编号
            Menu menu = menuService.getMenuById(orderMenuId);
            if (menu == null) {
                System.out.println("============菜品号不存在============");
                return;
            }

            //点餐
            if (billService.orderMenu(orderMenuId, orderNums, orderDiningTableId)) {
                System.out.println("============点餐成功============");
            } else {
                System.out.println("============点餐失败============");
            }

            //新增是否还要继续点餐功能,用循环实现
            System.out.print("请确认是否还要继续点餐(Y/N): ");
            Scanner scanner = new Scanner(System.in);
            String continueOrdering = scanner.nextLine().trim().toUpperCase();
            if (continueOrdering.equals("Y")) {
                continue;
            } else if (continueOrdering.equals("N")) {
                looping = false;
            }
        }

在进入点餐服务并输入餐桌号后开始进入循环
looping = true; //切记不要忘记在最后要把looping即循环条件重新置为true
具体实现如下图: 

 

细节:我将while循环放在了输入点餐桌号之后的代码里,这样就不用再次输入一次餐桌号点餐了,也符合连续点餐的逻辑。

3,消除账单

--在观看过程中我也是想到既然已经成功支付了账单,那按逻辑来说这一个餐桌的账单就应该从数-据库中被抹除,不然会造成账单冗余问题。
--方法依旧是非常简单,其实就是一个对表的删除语句编写。
--我同样是写在了BillService的类中,新增一个方法用于传给数据库删除的sql语句。

//完成结账后将账单删除的方法
    public void deleteBill(int diningTableId) {
        int update = billDAO.update("DELETE FROM bill WHERE diningTableId=?", diningTableId);
    }
 

 

然后在界面类中结账完成之后对方法进行一次调用即可
billService.deleteBill(diningTableId);
具体实现如下图所示:

 4,视频最后分表查询功能扩展问题

 最后老韩布置的任务即分表查询问题,我的思路是创建了一张detailEmployee表显示雇员的详细信息
然后在java 中创建对应的domain和DAO来对员工的详细信息进行查询
我将界面菜单设置成了这样两层(如下)

1代表顾客登录进行点餐等一些列操作, 2代表员工登录并显示该员工的详细信息,然后进行判断是否要显示该员工的详细信息(如下)

 

case "2":
                    while (loop3) {
                        System.out.print("输入员工号:");
                        String empId = Utility.readString(50);
                        System.out.print("输入密  码:");
                        String pwd = Utility.readString(50);
                        Employee employee = employeeService.getEmployeeByIdAndPwd(empId, pwd);
                        if (employee != null) {
                            System.out.println("===============登陆成功[" + employee.getName() + "]===============\n");
                            System.out.print("是否要显示员工信息(Y/N):");
                            Scanner scanner = new Scanner(System.in);
                            String emp = scanner.nextLine().trim().toUpperCase();
                            if (emp.equals("Y")) {
                                List<DetailedEmployeeTable> list = detailedEmployeeService.PersonManage(empId);
                                System.out.println("员工编号\t\t员工姓名\t\t岗位\t\t学历\t\t电话号码\t\t\t结婚情况");
                                for (DetailedEmployeeTable detailedEmployeeTable : list) {
                                    System.out.println(detailedEmployeeTable.getEmpId() + "\t\t" + detailedEmployeeTable.getName()
                                            + "\t\t\t" + detailedEmployeeTable.getJob() + "\t\t" + detailedEmployeeTable.getEducation()
                                            + "\t\t" + detailedEmployeeTable.getTel() + "\t\t" + detailedEmployeeTable.getMarry());
                                }
                                System.out.println("==========显示完毕==========");
                                break;
                            } else if (emp.equals("N")) {
                                break;
                            }
                        } else {
                            System.out.println("登陆失败");
                            loop3 = false;
                        }
                    }
                    break; 

如上将登录操作和查询详细表的操作放在一个case情况下完成分表查询的任务 。

5,SQL语句实现

我使用的是NaviCat,但是sql语句都大相径庭,操作方面NaviCat想要写sql语句需要点击数据库并新建一个查询(如图所示)

--创建emp表(主键id,empid,name,pwd,job等
CREATE TABLE employee(
    id INT PRIMARY KEY AUTO_INCREMENT, -- 自增
    empId VARCHAR(50) UNIQUE NOT NULL DEFAULT '', -- 员工号
    pwd CHAR(32) NOT NULL DEFAULT '', -- 密码md5
    name VARCHAR(50) NOT NULL DEFAULT '', -- 姓名
    job VARCHAR(50) NOT NULL DEFAULT '' -- 岗位
) CHARACTER SET utf8;

--添加测试数据
INSERT INTO employee VALUES(NULL, '6668612',MD5('123456'),'张三丰','经理');
INSERT INTO employee VALUES(NULL, '6668622',MD5('123456'),'小龙女','服务员');
INSERT INTO employee VALUES(NULL, '6668633',MD5('123456'),'张无忌','收银员');
INSERT INTO employee VALUES(NULL, '666666',MD5('123456'),'老韩','经理');

SELECT* FROM diningTable;
SELECT* FROM employee;
DROP TABLE bill;
DROP TABLE diningTable;

--创建diningTable表(id,state,orderName,orderTel...)
CREATE TABLE diningTable(
				id INT PRIMARY KEY AUTO_INCREMENT, #自增,表示餐桌编号
				state VARCHAR(20) NOT NULL DEFAULT '', #餐桌的状态
				orderName VARCHAR(50) NOT NULL DEFAULT '', #预定人的名字
				orderTel VARCHAR(20) NOT NULL DEFAULT '' #电话号码
) CHARACTER SET utf8;
	
INSERT INTO diningTable VALUES (NULL, '空','','');
INSERT INTO diningTable VALUES (NULL, '空','','');
INSERT INTO diningTable VALUES (NULL, '空','','');

update diningTable SET state = '空', orderName='', orderTel='' where id=1;

--创建menu表(id,name,type,price)
#菜谱
CREATE TABLE menu (
				id INT PRIMARY KEY AUTO_INCREMENT, #自增,表示菜谱编号
				NAME VARCHAR(50) NOT NULL DEFAULT '', #菜品名称
				TYPE VARCHAR(50) NOT NULL DEFAULT '', #菜品种类
				price DOUBLE NOT NULL DEFAULT 0 #价格
) CHARACTER SET utf8;
#测试数据 
INSERT INTO menu VALUES(NULL, '八宝饭', '主食', 10);
INSERT INTO menu VALUES(NULL, '叉烧包', '主食', 20);
INSERT INTO menu VALUES(NULL, '宫保鸡丁', '热菜', 30);
INSERT INTO menu VALUES(NULL, '山药鲅鱼', '凉菜', 14);
INSERT INTO menu VALUES(NULL, '银丝卷', '甜食', 9);
INSERT INTO menu VALUES(NULL, '水煮鱼', '热菜', 26);
INSERT INTO menu VALUES(NULL, '甲鱼汤', '汤类', 100);
INSERT INTO menu VALUES(NULL, '鸡蛋汤', '汤类', 16);

SELECT * FROM menu;

#增加表bill账单表(id,billId,menuId,nums,billDate,money,state,diningTableId)
CREATE TABLE bill (
				id INT PRIMARY KEY AUTO_INCREMENT, #自增主键
				billID VARCHAR(50) NOT NULL DEFAULT '', #账单号可以按照自己的规则生成 UUID
				menuId INT NOT NULL DEFAULT 0, #菜品的编号,也可以使用外键
				nums INT NOT NULL DEFAULT 0, #份数
				money DOUBLE NOT NULL DEFAULT 0, #金额
				diningTableId INT NOT NULL DEFAULT 0, #餐桌
				billDate DATETIME NOT NULL, #订单日期
				state VARCHAR(50) NOT NULL DEFAULT '' #状态'未结账', '已经结账', '挂单'
) CHARACTER SET utf8;

SELECT * FROM bill;

#分表查询,先将详细的雇员表建起来然后后面再根据雇员的id进行对详细雇员表的查询
CREATE TABLE detailEmployee(
    /* 自增 */ id INT PRIMARY KEY AUTO_INCREMENT,
    /* 员工号 */ empId VARCHAR(50) UNIQUE NOT NULL DEFAULT '',
    /* 姓名 */ name VARCHAR(50) NOT NULL DEFAULT '',
    /* 岗位 */ job VARCHAR(50) NOT NULL DEFAULT '',
    /* 学历 */ education VARCHAR(50) NOT NULL DEFAULT '',
    /* 电话号码 */ Tel INT NOT NULL DEFAULT 0,
    /* 是否结婚 */ Marry VARCHAR(50) NOT NULL DEFAULT ''
) CHARACTER SET utf8;

#添加数据进表
INSERT INTO detailEmployee VALUES(NULL, '6668612','张三丰','经理','博士','13333333','已婚');
INSERT INTO detailEmployee VALUES(NULL, '6668622','小龙女','服务员','大专','13455555','未婚');
INSERT INTO detailEmployee VALUES(NULL, '6668633','张无忌','收银员', '本科','1223455','未婚');
INSERT INTO detailEmployee VALUES(NULL, '666666','老韩','经理','硕士','66668788','已婚');

SELECT * FROM detailEmployee;

 以上是所有表和其中数据的sql代码。

6,具体代码实现

Utils类

JDBCUtilsByDruid

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.FileInputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

/**
 * 基于 Druid数据库连接池的工具类
 */
public class JDBCUtilsByDruid {

    private static DataSource ds;

    //在静态代码块完成ds初始化
    static {
        Properties properties = new Properties();
        try {
            properties.load(new FileInputStream("src\\druid.properties"));
            ds = DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    //编写getConnection方法
    public static Connection getConnection() throws SQLException {
        return ds.getConnection();
    }

    //关闭连接,在数据库连接池技术中,close不是真的断掉连接,而是把Connection放回连接池
    public static void close(ResultSet resultSet, Statement statement, Connection connection) {

        try {
            if (resultSet != null) {
                resultSet.close();
            }
            if (statement != null) {
                statement.close();
            }
            if (connection != null) {
                connection.close();
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
}

Utility

/**
 * 工具类的作用:
 * 处理各种情况的用户输入,并且能够按照程序员的需求,得到用户的控制台输入。
 */

import java.util.Scanner;

/**
 *
 */
public class Utility {
    //静态属性。。。
    private static Scanner scanner = new Scanner(System.in);


    /**
     * 功能:读取键盘输入的一个菜单选项,值:1——5的范围
     *
     * @return 1——5
     */
    public static char readMenuSelection() {
        char c;
        for (; ; ) {
            String str = readKeyBoard(1, false);//包含一个字符的字符串
            c = str.charAt(0);//将字符串转换成字符char类型
            if (c != '1' && c != '2' &&
                    c != '3' && c != '4' && c != '5') {
                System.out.print("选择错误,请重新输入:");
            } else break;
        }
        return c;
    }

    /**
     * 功能:读取键盘输入的一个字符
     *
     * @return 一个字符
     */
    public static char readChar() {
        String str = readKeyBoard(1, false);//就是一个字符
        return str.charAt(0);
    }

    /**
     * 功能:读取键盘输入的一个字符,如果直接按回车,则返回指定的默认值;否则返回输入的那个字符
     *
     * @param defaultValue 指定的默认值
     * @return 默认值或输入的字符
     */

    public static char readChar(char defaultValue) {
        String str = readKeyBoard(1, true);//要么是空字符串,要么是一个字符
        return (str.length() == 0) ? defaultValue : str.charAt(0);
    }

    /**
     * 功能:读取键盘输入的整型,长度小于2位
     *
     * @return 整数
     */
    public static int readInt() {
        int n;
        for (; ; ) {
            String str = readKeyBoard(10, false);//一个整数,长度<=10位
            try {
                n = Integer.parseInt(str);//将字符串转换成整数
                break;
            } catch (NumberFormatException e) {
                System.out.print("数字输入错误,请重新输入:");
            }
        }
        return n;
    }

    /**
     * 功能:读取键盘输入的 整数或默认值,如果直接回车,则返回默认值,否则返回输入的整数
     *
     * @param defaultValue 指定的默认值
     * @return 整数或默认值
     */
    public static int readInt(int defaultValue) {
        int n;
        for (; ; ) {
            String str = readKeyBoard(10, true);
            if (str.equals("")) {
                return defaultValue;
            }

            //异常处理...
            try {
                n = Integer.parseInt(str);
                break;
            } catch (NumberFormatException e) {
                System.out.print("数字输入错误,请重新输入:");
            }
        }
        return n;
    }

    /**
     * 功能:读取键盘输入的指定长度的字符串
     *
     * @param limit 限制的长度
     * @return 指定长度的字符串
     */

    public static String readString(int limit) {
        return readKeyBoard(limit, false);
    }

    /**
     * 功能:读取键盘输入的指定长度的字符串或默认值,如果直接回车,返回默认值,否则返回字符串
     *
     * @param limit        限制的长度
     * @param defaultValue 指定的默认值
     * @return 指定长度的字符串
     */

    public static String readString(int limit, String defaultValue) {
        String str = readKeyBoard(limit, true);
        return str.equals("") ? defaultValue : str;
    }


    /**
     * 功能:读取键盘输入的确认选项,Y或N
     * 将小的功能,封装到一个方法中.
     *
     * @return Y或N
     */
    public static char readConfirmSelection() {
        System.out.print("确认是否预定(Y/N): ");
        char c;
        for (; ; ) {//无限循环
            //在这里,将接受到字符,转成了大写字母
            //y => Y n=>N
            String str = readKeyBoard(1, false).toUpperCase();
            c = str.charAt(0);
            if (c == 'Y' || c == 'N') {
                break;
            } else {
                System.out.print("选择错误,请重新输入:");
            }
        }
        return c;
    }

    /**
     * 功能: 读取一个字符串
     *
     * @param limit       读取的长度
     * @param blankReturn 如果为true ,表示 可以读空字符串。
     *                    如果为false表示 不能读空字符串。
     *                    <p>
     *                    如果输入为空,或者输入大于limit的长度,就会提示重新输入。
     * @return
     */
    private static String readKeyBoard(int limit, boolean blankReturn) {

        //定义了字符串
        String line = "";

        //scanner.hasNextLine() 判断有没有下一行
        while (scanner.hasNextLine()) {
            line = scanner.nextLine();//读取这一行

            //如果line.length=0, 即用户没有输入任何内容,直接回车
            if (line.length() == 0) {
                if (blankReturn) return line;//如果blankReturn=true,可以返回空串
                else continue; //如果blankReturn=false,不接受空串,必须输入内容
            }

            //如果用户输入的内容大于了 limit,就提示重写输入
            //如果用户如的内容 >0 <= limit ,我就接受
            if (line.length() < 1 || line.length() > limit) {
                System.out.print("输入长度(不能大于" + limit + ")错误,请重新输入:");
                continue;
            }
            break;
        }

        return line;
    }
}

DAO类

BasicDAO

import com.ryy.mhl.utils.JDBCUtilsByDruid;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

/**
 * 开发BasicDAo,是其他DAO的父类
 *
 * @param <T>
 */
public class BasicDAO<T> {
    private QueryRunner qr = new QueryRunner();

    //开发通用的dml方法,针对任意的表
    public int update(String sql, Object... parameters) {
        Connection connection = null;
        try {
            connection = JDBCUtilsByDruid.getConnection(); //通过Druid连接池拿到连接
            int update = qr.update(connection, sql, parameters); //执行dml操作的方法
            return update;
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            JDBCUtilsByDruid.close(null, null, connection);
        }
    }

    //如果是执行SELECT语句返回多行多列

    /**
     * @param sql        sql语句,可以有?
     * @param clazz      传入一个类的class对象 比如Actor.class
     * @param parameters 传入?的具体的值,可以是多个
     * @return 根据Actor.class返回对应的ArrayList集合
     */
    public List<T> queryMulti(String sql, Class<T> clazz, Object... parameters) {
        Connection connection = null;
        try {
            connection = JDBCUtilsByDruid.getConnection(); //通过Druid连接池拿到连接
            return qr.query(connection, sql, new BeanListHandler<T>(clazz), parameters);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            JDBCUtilsByDruid.close(null, null, connection);
        }
    }

    //返回单行多列
    public T querySingle(String sql, Class<T> clazz, Object... parameters) {
        Connection connection = null;
        try {
            connection = JDBCUtilsByDruid.getConnection(); //通过Druid连接池拿到连接
            return qr.query(connection, sql, new BeanHandler<T>(clazz), parameters);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            JDBCUtilsByDruid.close(null, null, connection);
        }
    }

    //若要返回单值
    public Object queryScalar(String sql, Object... parameters) {
        Connection connection = null;
        try {
            connection = JDBCUtilsByDruid.getConnection(); //通过Druid连接池拿到连接
            return qr.query(connection, sql, new ScalarHandler(), parameters);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            JDBCUtilsByDruid.close(null, null, connection);
        }
    }
}

BillDAO

DetailedEmployeeTableDAO

DiningTableDAO

 EmployeeDAO

MenuDAO

MultiTableDAO

以上这些DAO全部都只需要继承BasicDAO即可,没有其他多余代码

domain类

Bill

import java.time.LocalDateTime;
import java.util.Date;

/**
 * javabean 和bill表对应
 */
public class Bill {
    private Integer id;
    private String billId;
    private Integer menuId;
    private Integer nums;
    private Double money;
    private Integer diningTableId;
    private LocalDateTime billDate;
    private String state;

    public Bill() {
    }

    public Bill(Integer id, String billId, Integer menuId, Integer nums, Double money,
                Integer diningTableId, LocalDateTime billDate, String state) {
        this.id = id;
        this.billId = billId;
        this.menuId = menuId;
        this.nums = nums;
        this.money = money;
        this.diningTableId = diningTableId;
        this.billDate = billDate;
        this.state = state;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getBillId() {
        return billId;
    }

    public void setBillId(String billId) {
        this.billId = billId;
    }

    public Integer getMenuId() {
        return menuId;
    }

    public void setMenuId(Integer menuId) {
        this.menuId = menuId;
    }

    public Integer getNums() {
        return nums;
    }

    public void setNums(Integer nums) {
        this.nums = nums;
    }

    public Double getMoney() {
        return money;
    }

    public void setMoney(Double money) {
        this.money = money;
    }

    public Integer getDiningTableId() {
        return diningTableId;
    }

    public void setDiningTableId(Integer diningTableId) {
        this.diningTableId = diningTableId;
    }

    public LocalDateTime getBillDate() {
        return billDate;
    }

    public void setBillDate(LocalDateTime billDate) {
        this.billDate = billDate;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    @Override
    public String toString() {
        return  id +
                "\t\t" + menuId +
                "\t\t\t" + nums +
                "\t\t\t" + money +
                "\t" + diningTableId +
                "\t\t" + billDate +
                "\t\t" + state ;
    }
}

DetailedEmployeeTable

public class DetailedEmployeeTable {
    private Integer id;
    private String empId;
    private String name;
    private String job;
    private String education;
    private Integer Tel;
    private String Marry;

    public DetailedEmployeeTable() {
    }

    public DetailedEmployeeTable(Integer id, String empId, String name,
                                 String job, String education, Integer tel, String marry) {
        this.id = id;
        this.empId = empId;
        this.name = name;
        this.job = job;
        this.education = education;
        Tel = tel;
        Marry = marry;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getEmpId() {
        return empId;
    }

    public void setEmpId(String empId) {
        this.empId = empId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getJob() {
        return job;
    }

    public void setJob(String job) {
        this.job = job;
    }

    public String getEducation() {
        return education;
    }

    public void setEducation(String education) {
        this.education = education;
    }

    public Integer getTel() {
        return Tel;
    }

    public void setTel(Integer tel) {
        Tel = tel;
    }

    public String getMarry() {
        return Marry;
    }

    public void setMarry(String marry) {
        Marry = marry;
    }
}

DiningTable

/**
 * 这是一个javabean和diningTable对应
 */
    public class DiningTable {
    private Integer id;
    private String state;
    private String orderName;
    private String oderTel;

    public DiningTable() {
    }

    public DiningTable(Integer id, String state, String orderName, String oderTel) {
        this.id = id;
        this.state = state;
        this.orderName = orderName;
        this.oderTel = oderTel;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    public String getOrderName() {
        return orderName;
    }

    public void setOrderName(String orderName) {
        this.orderName = orderName;
    }

    public String getOderTel() {
        return oderTel;
    }

    public void setOderTel(String oderTel) {
        this.oderTel = oderTel;
    }

    @Override
    public String toString() {
        return id + "\t\t\t" + state;
    }
}

Employee

/**
 * 这是一个javabean和 employee表对应
 */
public class Employee {
    private Integer id;
    private String empId;
    private String pwd;
    private String name;
    private String job;

    public Employee() { //一定先提供无参构造器,底层apache-dbutils反射需要
    }

    public Employee(Integer id, String empId, String pwd, String name, String job) {
        this.id = id;
        this.empId = empId;
        this.pwd = pwd;
        this.name = name;
        this.job = job;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getEmpId() {
        return empId;
    }

    public void setEmpId(String empId) {
        this.empId = empId;
    }

    public String getPwd() {
        return pwd;
    }

    public void setPwd(String pwd) {
        this.pwd = pwd;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getJob() {
        return job;
    }

    public void setJob(String job) {
        this.job = job;
    }
}

Menu

public class Menu {
    private Integer id;
    private String name;
    private String type;
    private Double price;

    public Menu() {
    }

    public Menu(Integer id, String name, String type, Double price) {
        this.id = id;
        this.name = name;
        this.type = type;
        this.price = price;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public Double getPrice() {
        return price;
    }

    public void setPrice(Double price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return id + "\t\t\t" + name + "\t\t" + type + "\t\t" + price;
    }
}

MultiTableBean

import java.time.LocalDateTime;

/**
 * 这是一个javabean 可以和多张表进行对应
 */
public class MultiTableBean {
    private Integer id;
    private String billId;
    private Integer menuId;
    private Integer nums;
    private Double money;
    private Integer diningTableId;
    private LocalDateTime billDate;
    private String state;
    //增加一个来自menu表的列 name
    private String name;

    public MultiTableBean() {
    }

    public MultiTableBean(Integer id, String billId, Integer menuId, Integer nums, Double money,
                          Integer diningTableId, LocalDateTime billDate, String state, String name) {
        this.id = id;
        this.billId = billId;
        this.menuId = menuId;
        this.nums = nums;
        this.money = money;
        this.diningTableId = diningTableId;
        this.billDate = billDate;
        this.state = state;
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getBillId() {
        return billId;
    }

    public void setBillId(String billId) {
        this.billId = billId;
    }

    public Integer getMenuId() {
        return menuId;
    }

    public void setMenuId(Integer menuId) {
        this.menuId = menuId;
    }

    public Integer getNums() {
        return nums;
    }

    public void setNums(Integer nums) {
        this.nums = nums;
    }

    public Double getMoney() {
        return money;
    }

    public void setMoney(Double money) {
        this.money = money;
    }

    public Integer getDiningTableId() {
        return diningTableId;
    }

    public void setDiningTableId(Integer diningTableId) {
        this.diningTableId = diningTableId;
    }

    public LocalDateTime getBillDate() {
        return billDate;
    }

    public void setBillDate(LocalDateTime billDate) {
        this.billDate = billDate;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    @Override
    public String toString() {
        return id +
                "\t\t" + menuId +
                "\t\t\t" + nums +
                "\t\t\t" + money +
                "\t" + diningTableId +
                "\t\t" + billDate +
                "\t\t" + state +
                "\t" + name;
    }
}

Service类

BillService

import com.ryy.mhl.dao.BillDAO;
import com.ryy.mhl.dao.MultiTableDAO;
import com.ryy.mhl.domain.Bill;
import com.ryy.mhl.domain.MultiTableBean;

import java.util.List;
import java.util.UUID;

/**
 * 处理和账单相关的业务逻辑
 */
public class BillService {
    //定义BillDAO属性
    private BillDAO billDAO = new BillDAO();
    //定义MenuService属性
    private MenuService menuService = new MenuService();
    //定义DiningTableService属性
    private DiningTableService diningTableService = new DiningTableService();
    //定义MultiTableDAO属性
    private MultiTableDAO multiTableDAO = new MultiTableDAO();

    //编写点餐的方法
    //1.生成账单
    //2.需要更新对应餐桌的状态
    //3.如果成功返回真,失败就返回false
    public boolean orderMenu(int menuId, int nums, int diningTableId) {
        //生成一个账单号,UUID
        String billID = UUID.randomUUID().toString();

        //将账单生成到bill表,要求直接计算账单金额
        /*注意此时要拿到菜品的价格就要去MenuService类中再创建一个方法能够返回菜品的价格进行计算*/
        int update = billDAO.update("insert into bill values(null,?,?,?,?,?,now(),'未结账')",
                billID, menuId, nums, menuService.getMenuById(menuId).getPrice() * nums, diningTableId);
        if (update <= 0) {
            return false;
        }

        //需要更新对应餐桌的状态
        return diningTableService.updateDiningTableState(diningTableId, "就餐中");
    }

    //返回所有的账单,提供给View调用
    public List<Bill> list() {
        return billDAO.queryMulti("select * from bill", Bill.class);
    }

    //使用多表查询返回在一张表内(返回所有账单并显示菜品名
    public List<MultiTableBean> list2() {  //注意在拼接sql语句的时候最后一定要带上空格
        return multiTableDAO.queryMulti("SELECT bill.*,NAME "
                + "FROM bill,menu "
                + "WHERE bill.menuId = menu.id",MultiTableBean.class);
    }

    //查看某个餐桌是否有未结账的账单
    public boolean hasPayBillByDiningTableId(int diningTableId) {
        Bill bill = billDAO.querySingle("SELECT * FROM bill WHERE diningTableId=? AND state='未结账' LIMIT 0, 1",
                Bill.class, diningTableId);
        return bill != null;
    }

    //完成结账[如果餐桌存在,并且该餐桌有未结账的账单]
    public boolean payBill(int dinningTableId, String payMode) {
        //1. 修改bill表
        int update = billDAO.update("update bill set state=? where diningTableId=? and state='未结账'",
                payMode, dinningTableId);
        if (update <= 0) { //更新失败情况
            return false;
        }
        //2. 修改diningTable表
        //注:不要直接在这里操作,而应该调用DiningTableService方法,更新餐桌就应该在餐桌类里修改以体现出各司其职
        if (!diningTableService.updateDiningTableToFree(dinningTableId, "空")) {
            return false;
        }
        return true;
    }

    //完成结账后将账单删除的方法
    public void deleteBill(int diningTableId) {
        int update = billDAO.update("DELETE FROM bill WHERE diningTableId=?", diningTableId);
    }
}

DetailedEmployeeService

import com.ryy.mhl.dao.DetailedEmployeeTableDAO;
import com.ryy.mhl.domain.DetailedEmployeeTable;

import java.util.List;

public class DetailedEmployeeService {
    private DetailedEmployeeTableDAO detailedEmployeeTableDAO = new DetailedEmployeeTableDAO();

    public List<DetailedEmployeeTable> PersonManage(String empId) {
        List<DetailedEmployeeTable> list =
                detailedEmployeeTableDAO.queryMulti("select * from detailEmployee where empId=?",
                        DetailedEmployeeTable.class, empId);
        return list;
    }
}

DiningTableService

import com.ryy.mhl.dao.DiningTableDAO;
import com.ryy.mhl.domain.DiningTable;

import java.util.List;

public class DiningTableService {
    //定义一个DiningTableDAO对象以后要对DAo里面的内容进行调用
    private DiningTableDAO diningTableDAO = new DiningTableDAO();

    //返回所有餐桌的信息
    public List<DiningTable> list() {
        List<DiningTable> diningTables =
                diningTableDAO.queryMulti("select id, state from diningTable", DiningTable.class);
        return diningTables;
    }

    //根据id,查询对应餐桌的DiningTable对象
    //如果返回null,表示餐桌的id不存在
    public DiningTable getDiningTableById(int id) {
        return diningTableDAO.querySingle("select * from diningTable where id = ?", DiningTable.class, id);
    }

    //如果餐桌可以预定,调用方法,对其状态进行更新(包括预定人的名字和电话)
    public boolean orderDiningTable(int id, String orderName, String orderTel) {
        int update = diningTableDAO.update
                ("update diningTable set state = '已经预定', orderName=?, orderTel=? where id=?",
                        orderName, orderTel, id);
        return update > 0; //大于0表示更新成功了
    }

    //需要提供一个更新餐桌状态的方法
    public boolean updateDiningTableState(int id, String state) {
        int update = diningTableDAO.update("update diningTable set state=? where id=?", state, id);
        return update > 0;
    }

    //提供方法,将指定的餐桌设置为空闲状态
    public boolean updateDiningTableToFree(int id, String state) {
        int update = diningTableDAO.update("update diningTable set state=?,orderName='',orderTel='' where id=?", state, id);
        return update > 0;
    }
}

EmployeeService

import com.ryy.mhl.dao.EmployeeDAO;
import com.ryy.mhl.domain.Employee;

/**
 * 该类完成对employee表的各种操作(通过调用EmployeeDAO完成)
 */
public class EmployeeService {

    //定义一个EmployeeDAO属性
    private EmployeeDAO employeeDAO = new EmployeeDAO();

    //方法,根据 empId 和 pwd 返回一个Employee对象
    //如果查询不到就返回null
    public Employee getEmployeeByIdAndPwd(String empId, String pwd) {
        Employee employee = employeeDAO.querySingle("select * from employee where empId=? and pwd=MD5(?)",
                Employee.class, empId, pwd);
        return employee;
    }
}

MenuService

import com.ryy.mhl.dao.MenuDAO;
import com.ryy.mhl.domain.Menu;

import java.util.List;

/**
 * 完成对menu表的各种操作(通过调用MenuDAO)
 */
public class MenuService {

    //定义MenuDAO属性
    private MenuDAO menuDAO = new MenuDAO();

    //返回所有的菜品,返回给界面使用
    public List<Menu> list() {
        return menuDAO.queryMulti("select * from menu", Menu.class);
    }

    //需要方法,根据id,返回Menu对象
    //验证菜品是否存在的方法
    public Menu getMenuById (int id) {
        return menuDAO.querySingle("select * from menu where id=?", Menu.class, id);
    }
}

View类

MHLView

import com.ryy.mhl.domain.*;
import com.ryy.mhl.service.*;
import com.ryy.mhl.utils.Utility;

import java.util.List;
import java.util.Scanner;

public class MHLView {

    //控制是否退出菜单
    private boolean loop = true;
    private boolean loop2 = true;
    private boolean loop3 = true;
    private String key = ""; //接收用户选择
    //定义EmployeeService属性
    private EmployeeService employeeService = new EmployeeService();
    //调用DiningTable的属性
    private DiningTableService diningTableService = new DiningTableService();
    //定义MenuService属性
    private MenuService menuService = new MenuService();
    //定义BillService属性
    private BillService billService = new BillService();
    //定义DetailedEmployeeService属性
    private DetailedEmployeeService detailedEmployeeService = new DetailedEmployeeService();

    public static void main(String[] args) {
        new MHLView().mainMenu();
    }

    //完成结账
    public void payBill() {
        System.out.println("============结账服务============");
        System.out.print("请选择要结账的餐桌编号(-1退出):");
        int diningTableId = Utility.readInt();
        if (diningTableId == -1) {
            System.out.println("============取消结账============");
            return;
        }
        //验证餐桌是否存在
        DiningTable diningTable = diningTableService.getDiningTableById(diningTableId);
        if (diningTable == null) {
            System.out.println("============结账的餐桌不存在============");
            return;
        }
        //验证餐桌是否有需要结账的账单
        if (!billService.hasPayBillByDiningTableId(diningTableId)) {
            System.out.println("============该餐桌没有未结账账单============");
            return;
        }
        System.out.print("结账方式(现金/微信/支付宝)回车表示退出:");
        String payMode = Utility.readString(20, ""); //说明:如果回车,就是返回“”
        if ("".equals(payMode)) {
            System.out.println("============取消结账============");
            return;
        }
        char key = Utility.readConfirmSelection();
        if (key == 'Y') {
            //调用BillService里的结账方法
            if (billService.payBill(diningTableId, payMode)) {
                System.out.println("============完成结账!============");
                billService.deleteBill(diningTableId);
            } else {
                System.out.println("============结账失败...============");
            }
        } else {
            System.out.println("============取消结账============");
        }
    }

    //显示账单信息
    public void listBill() {
//        List<Bill> bills = billService.list();
//        System.out.println("\n编号\t\t菜品号\t\t菜品量\t\t金额\t\t桌号\t\t日期\t\t\t\t\t\t状态");
//        for (Bill bill : bills) {
//            System.out.println(bill);
//        }
//        System.out.println("============显示完毕============");
        List<MultiTableBean> multiTableBeans = billService.list2();
        System.out.println("\n编号\t\t菜品号\t\t菜品量\t\t金额\t\t桌号\t\t日期\t\t\t\t\t\t状态\t\t菜品名");
        for (MultiTableBean bill : multiTableBeans) {
            System.out.println(bill);
        }
        System.out.println("============显示完毕============");
    }

    //完成点餐
    public void orderMenu() {
        System.out.println("============点餐服务============");
        System.out.print("请输入点餐的桌号(-1退出):");
        int orderDiningTableId = Utility.readInt();
        if (orderDiningTableId == -1) {
            System.out.println("============取消点餐============");
            return;
        }
        while (loop2) {
            System.out.print("请输入点餐的菜品号(-1退出):");
            int orderMenuId = Utility.readInt();
            if (orderMenuId == -1) {
                System.out.println("============取消点餐============");
                return;
            }
            System.out.print("请输入点餐的菜品量(-1退出):");
            int orderNums = Utility.readInt();
            if (orderNums == -1) {
                System.out.println("============取消点餐============");
                return;
            }

            //验证餐桌号是否存在
            DiningTable diningTable = diningTableService.getDiningTableById(orderDiningTableId);
            if (diningTable == null) {
                System.out.println("============餐桌号不存在============");
                return;
            }
            //验证菜品编号
            Menu menu = menuService.getMenuById(orderMenuId);
            if (menu == null) {
                System.out.println("============菜品号不存在============");
                return;
            }

            //点餐
            if (billService.orderMenu(orderMenuId, orderNums, orderDiningTableId)) {
                System.out.println("============点餐成功============");
            } else {
                System.out.println("============点餐失败============");
            }

            //新增是否还要继续点餐功能,用循环实现
            System.out.print("请确认是否还要继续点餐(Y/N): ");
            Scanner scanner = new Scanner(System.in);
            String continueOrdering = scanner.nextLine().trim().toUpperCase();
            if (continueOrdering.equals("Y")) {
                continue;
            } else if (continueOrdering.equals("N")) {
                loop2 = false;
            }
        }
        loop2 = true;
    }

    //显示所有菜品
    public void listMenu() {
        List<Menu> list = menuService.list();
        System.out.println("\n菜品编号\t\t菜品名\t\t类别\t\t价格");
        for (Menu menu : list) {
            System.out.println(menu);
        }
        System.out.println("===============显示完毕===============");
    }

    //完成定座
    public void orderDiningTable() {
        System.out.println("==========预定餐桌===========");
        System.out.print("请选择要预定的餐桌编号(-1退出):");
        int orderId = Utility.readInt();
        if (orderId == -1) {
            System.out.println("===============取消预定餐桌===============");
            return;
        }
        char key = Utility.readConfirmSelection();
        if (key == 'Y') {

            //根据orderId返回对应的DiningTable对象,如果为null,说明该对象不存在
            DiningTable diningTable = diningTableService.getDiningTableById(orderId);
            if (diningTable == null) {
                System.out.println("==========预定餐桌不存在==========");
                return;
            }
            //判断该餐桌的状态是否为“空”
            if (!("空".equals(diningTable.getState()))) { //说明当前这个餐桌不是“空”状态
                System.out.println("==========该餐桌已被预定或处于就餐中==========");
                return;
            }

            System.out.print("预定人的名字:");
            String orderName = Utility.readString(50);
            System.out.print("预定人的电话:");
            String orderTel = Utility.readString(50);

            //更新餐桌状态
            if (diningTableService.orderDiningTable(orderId, orderName, orderTel)) {
                System.out.println("==========预定餐桌成功==========");
            } else {
                System.out.println("==========预定失败==========");
            }

        } else {
            System.out.println("==========取消预定餐桌==========");
        }
    }

    public void listDiningTable() {
        List<DiningTable> list = diningTableService.list();
        System.out.println("\n餐桌编号\t\t餐桌状态");
        for (DiningTable diningTable : list) {
            System.out.println(diningTable);
        }
        System.out.println("===============显示完毕===============");
    }

    //显示主菜单
    public void mainMenu() {
        while (loop) {
            System.out.println("===============满汉楼===============");
            System.out.println("\t\t 1 登录满汉楼");
            System.out.println("\t\t 2 登录满汉楼(员工)");
            System.out.println("\t\t 3 退出满汉楼");
            System.out.print("请输入你的选择:");
            key = Utility.readString(1);
            switch (key) {
                case "1":
                    //显示二级菜单
                    while (loop) {
                        System.out.println("\n===============满汉楼(二级菜单)===============");
                        System.out.println("\t\t 1 显示餐桌状态");
                        System.out.println("\t\t 2 预定餐桌");
                        System.out.println("\t\t 3 显示所有菜品");
                        System.out.println("\t\t 4 点餐服务");
                        System.out.println("\t\t 5 查看账单");
                        System.out.println("\t\t 6 结账");
                        System.out.println("\t\t 9 退出满汉楼");
                        System.out.print("请输入你的选择:");
                        key = Utility.readString(1);
                        switch (key) {
                            case "1":
                                listDiningTable();
                                break;
                            case "2":
                                orderDiningTable();
                                break;
                            case "3":
                                listMenu();
                                break;
                            case "4":
                                orderMenu();
                                break;
                            case "5":
                                listBill();
                                break;
                            case "6":
                                payBill();
                                break;
                            case "9":
                                loop = false;
                                break;
                            default:
                                System.out.println("你的输入有误,请重新输入");
                                break;
                        }
                    }
                    break;
                case "2":
                    while (loop3) {
                        System.out.print("输入员工号:");
                        String empId = Utility.readString(50);
                        System.out.print("输入密  码:");
                        String pwd = Utility.readString(50);
                        Employee employee = employeeService.getEmployeeByIdAndPwd(empId, pwd);
                        if (employee != null) {
                            System.out.println("===============登陆成功[" + employee.getName() + "]===============\n");
                            System.out.print("是否要显示员工信息(Y/N):");
                            Scanner scanner = new Scanner(System.in);
                            String emp = scanner.nextLine().trim().toUpperCase();
                            if (emp.equals("Y")) {
                                List<DetailedEmployeeTable> list = detailedEmployeeService.PersonManage(empId);
                                System.out.println("员工编号\t\t员工姓名\t\t岗位\t\t学历\t\t电话号码\t\t\t结婚情况");
                                for (DetailedEmployeeTable detailedEmployeeTable : list) {
                                    System.out.println(detailedEmployeeTable.getEmpId() + "\t\t" + detailedEmployeeTable.getName()
                                            + "\t\t\t" + detailedEmployeeTable.getJob() + "\t\t" + detailedEmployeeTable.getEducation()
                                            + "\t\t" + detailedEmployeeTable.getTel() + "\t\t" + detailedEmployeeTable.getMarry());
                                }
                                System.out.println("==========显示完毕==========");
                                break;
                            } else if (emp.equals("N")) {
                                break;
                            }
                        } else {
                            System.out.println("登陆失败");
                            loop3 = false;
                        }
                    }
                    break;
                case "3":
                    loop = false;
                    break;
                default:
                    System.out.println("你的输入有误,请重新输入...");
            }
            System.out.println("你退出了满汉楼系统");
        }
    }
}

制作不易,喜欢的话请点个赞吧

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值