一、需求分析

1.系统背景

“民以食为天”,随着人民生活水平的提高,餐饮业在服务业中的地位越来越重要。然而餐饮行业蓬勃发展的同时,也带来了大量的食品浪费现象。经调查研究发现,在我校(上海建桥学院)食堂普遍存在,有的菜品满足不了学生的需要,而有的菜品却严重浪费的情况。因此,将应用软件应用于建桥学院的食堂管理系统中,可以解决传统的全靠人力的原料采购、统计、烹调、出售的服务流程,可以快速完成食堂的运转工作。原来费事费力的原料统计工作,现在只需要轻点几下鼠标和键盘,就能快捷的完成,既提高了工作效率,又节省了人力资源,为建桥学院食堂巨大人流量的创造了更便捷的发展空间。

2.系统功能结构(需包含功能结构框图和模块说明)

(1)功能结构图

功能结构图

(2)模块说明

1、部门管理模块
    包含每个部门的基本信息,部门人员的变动
2、后厨管理模块
    包含功能:查看原料余量,菜单管理,菜品制作
3、前台服务模块
    包含功能:获取菜品,出售菜品,自动结账
4、采购管理模块
    包含功能:联系供应商,查看原料余量,原料采购
5、系统安全模块
    账户登录,密码修改

3.系统功能简介

部门经理负责管理人员;厨师负责制作菜品,定菜单;前台负责出售菜品和收银;采购员负责采购,联系供应商;供应商负责提供原料。

二、概念模型设计

1.基本要素(符号介绍说明)

在这里插入图片描述

椭圆:表示实体的属性

方形:表示实体(表名)

菱形:表示实体之间的联系

2.ER图

在这里插入图片描述

三、逻辑模型设计

1.ER模型向关系模型转换规则

一个部门对应多个采购员;一个部门对应多个售菜员;一个部门对应多个厨师
多个采购员对应多个供应商;多个厨师对应多个菜品;多个售菜员对应多个菜品
多个菜品对应多个仓库

2.转换后的关系模型

部门(部门号,部门名称,办公室,电话)
采购员(采购员工号,姓名,性别,年龄,电话,所属部门)
供应商(供应商代码,供应商名称,联系方式,厂址)
采购(采购员工号,供应商代码,原料编号,数量)
售菜员(售菜员工号,姓名,性别,年龄,部门号)
厨师(厨师工号,姓名,性别,年龄,厨师等级,部门号)
菜品(菜品代码,菜名,所需原料,价格)
做菜(厨师工号,菜品代码,数量)
售菜(售菜员工号,菜品代码,数量)
库房(库房号,原料编号,原料名称,剩余量)

3.关系模型优化(达到3NF)

共计7个实体各自生成一张表;
采购员和供应商之间生成一张采购表;
厨师和菜品之间生成一张做菜表;
售菜员和菜品之间生成一张售菜表。

四、物理设计

1.创建数据库的SQL语句

create database JQST;
go 
use JQST
go

2.创建所有表的SQL语句或截图(包含完整性约束:实体、域、参考完整性等)

create table department(dno char(10)primary key,dname char(10)not null,office char(20),dtel char(20));
create table purchaser(pno char(10) primary key,pname char(10) not null,psex char(2)  check (psex in ('男','女')),page char(10) ,ptel char(20), dno char(10),foreign key (dno) references department (dno));
create table supplier(sno char(10) primary key,sname char(20) not null, stel varchar(50) ,sadd varchar(50));
create table buy(pno char(10), sno char(10),ingredient char(20),rnumber smallint, primary key (pno, sno));
create table waiter (wno char(10) primary key,wname char(10) not null,wsex char(2)  check (wsex in ('男','女')),wage char(10), dno char(10),foreign key (dno) references department (dno));
create table cook (cno char(10) primary key,cname char(10) not null,csex char(2)  check (csex in ('男','女')),cage char(10) ,cgrade char(20), dno char(10),foreign key (dno) references department (dno));
create table food (fno char(10) primary key,fname varchar(50) not null,ingredient char(20),price char(10));
create table cooking(cno char(10), fno char(10), fnumber smallint, primary key (cno, fno));
create table sell(wno char(10), fno char(10), snumber smallint, primary key (wno, fno));
create table warehouse (whno char(10),ingno char(10), ingredient char(20), numremaining char(20) primary key (whno, ingno));
go

五、数据库实施

1.数据库关系图

在这里插入图片描述

2.数据录入(部分)

insert into department values ('d001','管理部','A101','021-1111');
insert into purchaser values ('p001','李明','男','23', '13573369866','d003');
insert into supplier values ('s001','绿生源食品厂','021-6958723','上海市浦东新区方竹路233号');
insert into buy values ('p001','s001','鸡肉',100);
insert into waiter values ('w001','杨佳俞','女','38', 'd006');
insert into cook values ('c001','张共可','男','50', '国家特级','d004');
insert into food values ('f001','麻婆豆腐','豆腐','12');
insert into cooking values ('c001','f008',10);
insert into sell values ('w001','f001',16);
insert into warehouse values ('wh001','i01','鱼','20');

3.数据处理

(1)至少包括2张表的等值连接;

select pno 工号,pname 姓名, psex 性别,page 年龄,ptel 电话 ,dname 所属部门 from purchaser,department where purchaser.dno=department.dno

(2)创建视图;

create view bumen as select * from department

(3)编写包含子查询的SQL语句;

select dname from department where dno = (select dno from purchaser where pno='p002');

(4)有修改语句;

update purchaser set ptel='110' where pno='p002'

(5)有删除语句;

delete from purchaser where pno='p002'

(6)有包含聚集函数;

select count(distinct(pname)) as 采购员人数 from purchaser 

(7)有记录过滤,条件过滤语句;

select * from purchaser where psex='男'

(8)有修改表结构的SQL语句;

alter table purchaser add padd int 

(9)用T-SQL语句写出一个对数据表处理的人机交互程序;

select  pname as 姓名,case psex when '男' then 'M' when '女' then 'l' end as 性别 from purchaser 

(10)编写一个触发器;

create trigger triGradeUpdate on purchaser for update as if UPDATE(ptel)
begin
print'员工的电话号码被修改了'
rollback
end

六、数据库应用系统实现

1.系统相关界面截图

登录界面
在这里插入图片描述

注册界面
在这里插入图片描述

主界面
在这里插入图片描述

查询界面
在这里插入图片描述

添加界面

在这里插入图片描述

修改界面
在这里插入图片描述

删除界面

在这里插入图片描述

2.与数据库连接的程序语句

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class GetConnection {    
private Connection con;            //定义数据库连接类对象
private String user="sa";        //连接数据库用户名
private String password="123456";        //连接数据库密码
private String className="com.microsoft.sqlserver.jdbc.SQLServerDriver";    //数据库驱动
private String url="jdbc:sqlserver://localhost:1433;DatabaseName=JQST";        //连接数据库的URL
static {// 通过静态方法加载数据库驱动
try{
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver").newInstance();// 加载数据库驱动
    } catch (Exception e) {
        e.printStackTrace();
    }
}
public GetConnection(){
    try{
        Class.forName(className);
    }catch(ClassNotFoundException e){
        System.out.println("加载数据库驱动失败!");
        e.printStackTrace();
    }
}
/**创建数据库连接*/
public Connection getCon(){
    try {
        con=DriverManager.getConnection(url,user,password);        //获取数据库连接
    } catch (SQLException e) {
        System.out.println("创建数据库连接失败!");
        con=null;
        e.printStackTrace();
    }
    return con;                    //返回数据库连接对象
}    
}

3.具体实现代码

登录的窗体设计

    /** * Launch the application.启动程序.*/
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    SwingUtilities.invokeLater(new Runnable() {                        public void run() {Enter mostly = new Enter();        
        mostly.setVisible(true); }                                                    });
    } catch (Exception e) {
    e.printStackTrace();
}
}
});
}
    /** * Create the frame.创建整个框架.*/
    public Enter() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(false);
        setLocationRelativeTo(null);// 窗体居中
        setTitle("上海建桥学院食堂管理");
        setBounds(450, 150, 436, 358);
        contentPane =  getLoginPanel();
        setContentPane(contentPane);
        contentPane.setLayout(null);
    }
    /** * 初始化登录面板 */
    private BgEnter getLoginPanel() {
if (contentPane == null) {
            contentPane = new BgEnter();
            contentPane.setImage(getToolkit().getImage(
            getClass().getResource("/Images/denglu.jpg")));                        contentPane.setLayout(null);
            JLabel userNameLabel = new JLabel("用户名:");
            userNameLabel.setBounds(110, 180, 54, 15);
            contentPane.add(userNameLabel);
            userNameTextField = new JTextField();
            userNameTextField.setBounds(160, 180, 139, 25);
            contentPane.add(userNameTextField);
            userNameTextField.setColumns(10);
            JLabel passWordLabel = new JLabel("密  码:");
            passWordLabel.setBounds(110, 220, 54, 15);
            contentPane.add(passWordLabel);
            passwordField = new JPasswordField();
            passwordField.setBounds(160,220, 139, 25);
            contentPane.add(passwordField);
            JButton enterButton = new JButton("");
            URL url = getClass().getResource("/Images/in1.png");
            ImageIcon imageIcon = new ImageIcon(url);    
            enterButton.setBounds(0,1,imageIcon.getIconWidth(), imageIcon.getIconHeight());        
            enterButton.setIcon(imageIcon);            
            enterButton.setContentAreaFilled(false);                                enterButton.setBorder(null);
            enterButton.addActionListener(new ActionListener() {                public void actionPerformed(ActionEvent e) {
                        UserDao userDao = new UserDao();User user = userDao.getUser(userNameTextField.getText(),passwordField.getText());//以用户添加的用户名与密码为参数调用查询用户方法
                if(user.getId()>0){                                                                    Session.setUser(user);                                                        Frame frame = new Frame();                                                    frame.setVisible(true);                                                        Enter.this.dispose();}else{                                JOptionPane.showMessageDialog(getContentPane(), "用户名或密码错误");                            userNameTextField.setText("");                                                passwordField.setText("");}
                    }
        });
                enterButton.setBounds(105,260,210,50);
                contentPane.add(enterButton);
        }
        return contentPane;
    }
}
主界面的程序设计
public class Frame extends JFrame {
    GetConnection connection = new GetConnection();//命名加载数据库的驱动
    Connection conn = null;//连接
    public Frame() {    
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(280,50,796,550);//背景大小
        BJpanel contentPane = new BJpanel();//调用BJpanel背景添加图片
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        setTitle("上海建桥学院食堂管理系统");
        contentPane.setLayout(null);//设计布局,布局管理器为空
        setResizable(false);//窗口不可以变化大小
//定义一个panel,在下面显示的小界面
        final JPanel panel = new JPanel();
        panel.setBackground(new Color(255,225,225));
        panel.setBounds(35,180,730,330);
        panel.setLayout(null); 
        contentPane.add(panel);    
//第一个按钮 (把他单独写在一个新的里面)——FoodPanel    
        JButton jb1=new JButton("菜      品");
        setLayout(null);//改变布局方式
        jb1.setBackground(Color.white);
        jb1.setBounds(40,120,100,40);
        contentPane.add(jb1);//显示jb JButton
        jb1.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {//跳转出查询的界面
                panel.removeAll();
                FoodPanel foodPanel = new FoodPanel();
                panel.add(foodPanel.getMessage());
                repaint();                
            }
        });
//第二个按钮    ————SupplierPanel
        JButton jb2=new JButton("供  应  商");
        setLayout(null);//改变布局方式
        jb2.setBackground(Color.white);
        jb2.setBounds(200,120,100,40);
        contentPane.add(jb2);//显示jb JButton
        jb2.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {//跳转出查询的界面
                panel.removeAll();
                SupplierPanel supplierPanel = new SupplierPanel();
                panel.add(supplierPanel.getMessage());
                repaint();
            }
        });
//第三个按钮    ——————PurchaserPanel
        JButton jb3=new JButton("职   工");
        setLayout(null);//改变布局方式
        jb3.setBackground(Color.white);
        jb3.setBounds(500,120,100,40);
        contentPane.add(jb3);//显示jb JButton
        jb3.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {
                panel.removeAll();
                PurchaserPanel purchaserPanel = new PurchaserPanel();
                panel.add(purchaserPanel.getMessage());
                repaint();
            }            
        });
//第四个按钮    ——————WarehousePanel
        JButton jb4=new JButton("仓   库");
        setLayout(null);//改变布局方式
        jb4.setBackground(Color.white);
        jb4.setBounds(660,120,100,40);
        contentPane.add(jb4);//显示jb JButton
        jb4.addActionListener(new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent e) {
                panel.removeAll();
                WarehousePanel warehousePanel = new WarehousePanel();
                panel.add(warehousePanel.getMessage());
                repaint();
            }        
        });
    }
}
增加的主要代码:
JButton insertButton = new JButton("添加");
        insertButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                SupplierDao supplierDao = new SupplierDao();
                Supplier supplier = new Supplier();                
                String sno = snoTextField.getText();
                String sname = snameTextField.getText();
                String stel = stelTextField.getText();
                String sadd = saddTextField.getText();                
                if((sno.equals("")) || (sname.equals(""))  ||
                    (stel.equals("")) || (sadd.equals(""))){
                    JOptionPane.showMessageDialog(getContentPane(), "请将带星号的内容填写完整!","信息提示框", JOptionPane.INFORMATION_MESSAGE);
                    return;
                }
                supplier.setsno(sno);
                supplier.setsname(sname);
                supplier.setstel(stel);
                supplier.setsadd(sadd);
                supplierDao.insertSupplier(supplier);
                JOptionPane.showMessageDialog(getContentPane(), "数据添加成功!","信息提示框", JOptionPane.INFORMATION_MESSAGE);
            }
        });
修改的主要代码:
JButton uodatetButton = new JButton("修改");
        uodatetButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                String fno = fnoTextField.getText();
                String fname = fnameTextField.getText();
                String ingredient = ingredientTextField.getText();
                String price = priceTextField.getText();
                float unitPrice = 0;
    if((fno.equals(""))||(fname.equals(""))||(price.equals(""))||(ingredient.equals(""))){JOptionPane.showMessageDialog(getContentPane(), "将带星号的信息填写完整!","信息提示框", JOptionPane.INFORMATION_MESSAGE);
            return;
    }try{unitPrice = Float.parseFloat(price);
            }catch (Exception ee) {
                    JOptionPane.showMessageDialog(getContentPane(), "价格必须是数字!","信息提示框", JOptionPane.INFORMATION_MESSAGE);
                    return;
                }
                food.setfno(fnoTextField.getText());
                food.setfname(fnameTextField.getText());
                food.setingredient(ingredientTextField.getText());
                food.setprice(unitPrice);
                dao.updateFood(food);
                repaint();
                JOptionPane.showMessageDialog(getContentPane(), "数据修改成功!","信息提示框", JOptionPane.INFORMATION_MESSAGE);
            }
        });
删除的主要代码:
JButton deleteButton = new JButton("删除");
        deleteButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                int row = table.getSelectedRow();
                if (row < 0) {JOptionPane.showMessageDialog(getParent(), "没有选择要刪除的数据!","信息提示框", JOptionPane.INFORMATION_MESSAGE);
return;} else {String column =    foodModel.getValueAt(row, 0).toString();//写在里面才行,写在外面会报错
            foodDao.deleteFood(Integer.parseInt(column));//删除数据库数据                JOptionPane.showMessageDialog(getParent(), "数据删除成功!","信息提示框", JOptionPane.INFORMATION_MESSAGE);repaint();}}});

七、总结

通过这次数据库的实践课程,学习到了很多,大致完成了自己实验前的计划,项目也到达了预期的效果,整个项目以建桥食堂的运营为基础,通过采购员,厨师,销售员,以及仓库为主体,贯穿菜品从采购到制作最后售出的整个过程。虽然项目比较简陋,但是仍然遇到了很多问题和自己知识点的漏洞,比如数据库建表阶段,出现了主键外键设置不当的问题,触发器设置影响了后期程序运行的问题,通过自己查阅资料,和老师同学的交流过程中,也都能一一解决了,激发了自己日后更加深入学习的积极性。之后在设计项目时,一定先要做好总体的设计,否则会造成后期思路不清,项目混乱的现象。

参考文献:

《Java从入门到精通(第5版)》 明日科技 2019-02 清华大学出版社
《数据库技术及应用》 谷伟 2017-09 中国铁路出版社
《Java程序设计案例教程》 李伟 2015-08 清华大学出版社