一、需求分析
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 清华大学出版社