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