资源描述
邮局报刊管理系统
南京农业大学信息科技学院
数据库课程设计报告
设计题目:邮局订报管理系统
专 业:计算机科学与技术
班 级:
组 长:
成 员:
指导老师: 黄芬
日 期:2009年11月2日
成 绩:
39
目录
1.开发环境和相关技术介绍 1
1.1开发环境 1
1.2相关技术介绍 1
2.需求分析 1
2.1系统需求和功能 1
2.1.1系统需求 1
2.1.2系统功能 1
2.2数据字典 2
2.2.1数据结构 2
2.2.2数据项 2
2.2.3数据流 2
2.3数据流图 3
2.4安全性要求 3
3.概念结构设计 3
3.1设计方法和步骤 4
3.2概念结构E-R图 4
4.逻辑结构设计 6
4.1关系模式设计与优化分析 6
4.1.1关系模式设计 6
4.1.2优化分析 6
4.2系统结构图 8
4.3系统完整性设计 8
5.数据库物理设计 9
5.1数据存放位置 9
5.2确定系统配置 9
5.3模块设计 9
5.3.1登陆模块 9
5.3.2管理模块 9
5.3.3管理账户模块 10
5.3.4查询模块 10
6.数据库实施 10
6.1数据库构建 10
6.1.1各数据表说明 10
6.1.2数据库创建 11
6.2数据库分离和恢复方案 11
6.2.1分离数据库 11
6.2.2恢复数据库 11
7.应用界面设计和应用程序编码 12
7.1用户界面设计 12
7.2类文件功能描述 13
7.3主要代码分析 13
8.系统测试 19
8.1测试方案 20
8.2测试过程 20
8.2.1登陆测试 20
8.2.2主界面各子模块测试 21
9.安装和使用说明 38
9.1安装说明 38
9.1.1安装Java运行环境JRE 38
9.1.2安装Microsoft SQL Server 2000 JDBC驱动程序 38
9.1.3升级Microsoft SQL Server 2000数据库管理系统 38
9.1.4附加数据库 38
9.1.5可能出现情况 38
9.2使用说明 38
10.完成情况和总结 38
10.1完成情况 38
10.2总结 39
【参考文献】 39
1.开发环境和相关技术介绍
1.1开发环境
数据库系统:Microsoft SQL Server 2000 sp4
开发语言:JAVA
数据库连接方式:JDBC连接方式
开发工具:Eclipse 3.3
1.2相关技术介绍
Microsoft SQL Server 2000数据库管理系统是微软公司研制开发的关系型数据库管理系统。该系统支持并扩展了SQL语言标准,可以运用标准SQL语句对数据进行操作,也可以使用功能强大的GUI工具进行灵活的数据管理。同时,系统还提供功能完善的API,可以在应用程序中调用这些API来实现与数据库系统的连接以及相关数据的操作。Sp4是该系统的一个版本号,SQL Server 2000 SP3以上的版本才可以支持纯JDBC的连接方式。
Eclipse:功能强大的应用程序开发工具,主要支持基于Java语言的各种开发项目。灵活的Plun-in功能,可以根据具体需要安装各种插件。
JDBC连接方式:Java与数据库系统的一种连接方式,Java程序使用JDBC API与数据库进行通信,并用它操作数据库中的数据。JDBC API使Java程序与具体数据库系统独立开来,保证了Java程序高度的可移植性。
2.需求分析
2.1系统需求和功能
2.1.1系统需求
设计本系统模拟客户在邮局订购报刊的管理内容,包括查询报刊、订报刊、订购后的查询、统计等的处理情况,系统需要管理的情况如下:
(1)可随时查询出可订购报纸的情况,如报刊编号(PNO)、报刊名称(PNA)、单价(PPR)、出版单位(PDW)等,这样便于用户选订。
(2)客户订购报刊时,可订购多种报刊,每种报刊可订若干份。
(3)为便于邮局投递报刊,客户需提供如下信息:客户编码(CID)、客户姓名(CNA)、联系电话(CTE)、联系地址(CAD)、邮编(CPC)。
(4)邮局对每种报刊的订购人数不限,每个客户可多次订购报刊,所订报刊亦可重复。
2.1.2系统功能
1. 客户可到邮局通过管理员查询可订购报刊的详细情况。
2.客户通过管理员根据自己的需求订购报刊,完成一次订购后需进行结账才能提交订单。
3.客户可以通过管理员查询自己的订报情况。
4.管理员可以登录系统对各库表进行插入、修改、删除、查询等基本操作。
5.管理员每次要添加一个新客户时,由客户提供各种信息。
6.每次要添加一个新的订单时,系统会自动为该订单编制唯一的订单编号,然后管理员根据客户订刊要求填写订单并结账收费。
7.管理员能详细查询某报刊的订出情况,并且能统计出某报刊的总订数量与总金额。
8.管理员可以管理客户、报刊、订单和系统账户,对系统进行维护。
2.2数据字典
2.2.1数据结构
管理员 = 管理员账号+管理员密码
客户 = 客户编号+客户姓名+联系电话+联系地址+邮编
报刊 = 报刊编号+报刊名+单价+出版单位+备注
订单 = 订单编号+客户编号+订刊日期
详细订单 = 订单编号+报刊编号+订刊份数+期数+单价+总金额
2.2.2数据项
表2.1数据项表
编号
标识符
类型
长度
所属表名
同义名
1
AID
char
20
Admin
管理员账号
2
APW
char
20
Admin
管理员密码
3
CID
char
8
Customer,Oder
客户编号
4
CNA
char
20
Customer
客户姓名
5
CTE
char
15
Customer
联系电话
6
CAD
char
50
Customer
联系地址
7
CPC
char
10
Customer
邮编
8
PNO
char
6
Paper,Orderdetail
报刊编号
9
PNA
char
50
Paper
报刊名
10
PPR
float
8
Paper,Oderdetail
单价
11
PDW
char
50
Paper
出版单位
12
PREM
char
20
Paper
备注
13
ONO
char
10
Oder,Orderdetail
订单编号
14
ODATE
datetime
8
Oder
订刊日期
15
NUM
int
4
Orderdetail
订刊份数
16
QISHU
int
4
Orderdetail
期数
17
TOTAL
float
8
Orderdetail
总金额
2.2.3数据流
表2.2数据流表
编号
名称
来源
去向
组成
1
身份信息
系统管理员
应用系统
管理员账号+密码
2
授权信息
应用系统
系统管理员
3
错误身份信息
应用系统
系统管理员
4
查询请求
系统管理员
应用系统
待查询对象识别符
5
查询结果
应用系统
系统管理员
被查询对象具体信息
6
管理请求
系统管理员
应用系统
识别符+管理类型
7
管理结果信息
应用系统
系统管理员
被管理对象处理结果
8
非法请求
应用系统
系统管理员
非法请求提示信息
2.3数据流图
系 统 管 理 员
报 刊 订 阅 应 用 系 统
身份信息
授权信息
错误身份信息
查询请求
查询结果信息
信息管理请求
管理结果信息
非法请求
图2.1报刊订阅系统顶层图
2.4安全性要求
在数据库内设有管理员表,登陆系统时会要求输入管理员账号和密码。登陆模块根据输入账号和密码查管理员表,查到匹配记录则允许其登陆系统。管理员账号和密码可以在登陆系统后添加和修改。
3.概念结构设计
3.1设计方法和步骤
采用自底而上的设计方法。先自顶向下地进行需求分析,对报刊订阅管理系统的需求进行逐步细化;然后再自底而上地设计概念结构,最终将各个局部应用的概念结构集合成为全局概念结构。
3.2概念结构E-R图
通过对局部应用的选择,逐一设计出分E-R图,并对各个分E-R图进行合并,生成初步E-R图,消除不必要的系统冗余,可以得出订报管理系统E-R图。
Customer
CID
CAD
CTE
CNA
CPC
图3.1客户E-R图
PNO
PNA
PREM
Paper
PPR
PDW
图3.2报刊E-R图
Oder
ONO
CID
ODATE
图3.3订单E-R图
ONO
PNO
QISHU
TOTAL
PPR
NUM
Orderdetail
图3.4详细订单E-R图
Admin
AID
APW
图3.5管理员E-R图
CPC
CID
PPR
PDW
PREM
PNA
PNO
CNA
CTE
CAD
APW
AID
TOTAL
QISHU
NUM
PPR
PNO
CID
ONO
P/O
C/O
Paper
Admin
Customer
Orderdetail
1
ODATE
n
m
n
ONO
n
1
O/O
Oder
图3.6订报管理系统E-R图
4.逻辑结构设计
4.1关系模式设计与优化分析
4.1.1关系模式设计
根据概念结构的设计,可以将系统E-R图转换为以下关系模式(画横线的为各关系的码):
Customer(CID,CNA,CTE,CAD,CPC)
Paper(PNO,PNA,PDW,PPR,PREM)
Oder(ONO,CID,ODATE)
Foreign key:CID
Orderdetail(ONO,PNO,PPR,NUM,QISHU,TOTAL)
Foreign key:ONO,PNO
Admin(AID,APW)
4.1.2优化分析
考察关系模式:Customer(CID,CNA,CTE,CAD,CPC):
CID—>CNA
CID—>CTE
CID—>CAD
CID—>CPC
它只有一个码:CID,这里没有任何属性对CID部分依赖或传递依赖,所以此关系模式属于3NF,由于此关系模式中CID是唯一的决定因素,所以该关系模式属于BCNF.
考察关系模式:Paper(PNO,PNA,PDW,PPR,PREM):
PNO—>PNA
PNO—>PDW
PNO—>PPR
PNO—>PREM
它只有一个码:PNO,这里没有任何属性对PNO部分依赖或传递依赖,所以此关系模式属于3NF,由于此关系模式中PNO是唯一的决定因素,所以该关系模式属于BCNF.
考察关系模式:Order(ONO,CID,ODATE):
ONO—>CID
ONO—>ODATE
它只有一个码:ONO,这里没有任何属性对ONO部分依赖或传递依赖,所以此关系模式属于3NF,由于此关系模式中ONO是唯一的决定因素,所以该关系模式属于BCNF.
考察关系模式:Orderdetail(ONO,PNO,NUM,PPR,QISHU,TOTAL):
(ONO,PNO)—>NUM
(ONO,PNO)—>PPR
(ONO,PNO)—>QISHU
(ONO,PNO)—>TOTAL
(NUM,PPR,QISHU)—>TOTAL
由上每个非主属性完全函数依赖于码可得出该关系模式属于2NF,由于属性TOTAL还完全依赖于非码属性组(NUM,PPR,QISHU),故不满足3NF.
关系模式:Admin(AID,APW)
AID—>APW显然属于BCNF.
4.2系统结构图
退出系统
添加报刊
邮局订报管理系统
报刊管理
订单管理
客户管理
账户管理
数据统计
删除报刊
修改报刊
查询
删除客户
修改客户
删除订单
添加订单
查询
删除管理员
添加客户
修改管理员
添加管理员
查询
按报刊编号查询
按报刊名查询
按订单编号查询
按客户编号查询
按客户编号查询
按客户姓名查询
查询所有报刊
查询所有客户
查询所有订单
查询订单详情
修改订单项
删除订单项
图4.1
4.3系统完整性设计
Customer (CID,CNA,CTE,CAD,CPC)
其中:CID为主码,CID,CAN,CTE,CAD,CPC约束都为非空
Paper (PNO, PNA, PDW,PPR,PREM)
其中:PNO为主码,PNA,PPR约束为非空
Oder (ONO, CID, ODATE)
其中:ONO为主码,CID为外码(参照对象为Customer(CID))
Orderdetail (ONO, PNO, NUM,PPR,QISHU,TOTAL)
其中:(ONO,PNO)为主码,ONO和PNO分别为外码,(参照分别为:Oder(ONO)和Paper(PNO);NUM,PPR,QISHU,TOTAL都约束为非空
Admin(AID,APW)
其中:AID为主码。
5.数据库物理设计
5.1数据存放位置
本系统数据存放在磁盘中。
5.2确定系统配置
根据具体需要配置。
5.3模块设计
5.3.1登陆模块
管理员账号
管理员密码
查看Admin表
确认身份进入系统
报出错误身份信息
图5.1
5.3.2管理模块
待添加节点信息
*待修改节点标示符
*操作类型(修改、删除)
*请求合法性检查
*检查是否有插入冲突
*完成节点添加
*请求合法性检查
*根据标识符查找节点
*执行相应操作
*处理结果
*显示错误信息
图5.2
5.3.3管理账户模块
*待修改ID和密码
*操作类型(添加、删除)
*待添加节点信息
*查找Admin表*执行相应操作
*信息完整性检查
*插入冲突检查
*插入节点
*处理结果
*显示错误信息
图5.3
5.3.4查询模块
待查询节点标示符
*请求合法性检查
*根据ID在相应表中查找记录
显示查找结果
显示错误信息
图5.4
6.数据库实施
6.1数据库构建
6.1.1各数据表说明
6.1数据说明表
编号
数据表名称
类型
内容
1
Admin
辅助表
记录管理员帐号,密码
2
Customer
主表
记录客户信息
3
Paper
主表
记录报刊信息
4
Oder
主表
记录订单基本信息
5
Orderdetail
主表
记录详细订单信息
6.1.2数据库创建
CREATE TABLE Admin
(AID CHAR(20) PRIMARY KEY NOT NULL,
APW CHAR(20) NOT NULL
);
CREATE TABLE Customer
(CID CHAR(8) PRIMARY KEY NOT NULL,
CNA CHAR(20) NOT NULL,
CTE CHAR(15) NOT NULL,
CAD CHAR(50) NOT NULL,
CPC CHAR(10) NOT NULL
);
CREATE TABLE Paper
(PNO CHAR(6) PRIMARY KEY NOT NULL ,
PNA CHAR(50) NOT NULL ,
PDW CHAR(50),
PPR FLOAT(8) NOT NULL,
PREM CHAR(20)
);
CREATE TABLE Oder
(ONO CHAR(10) PRIMARY KEY,NOT NULL ,
CID CHAR(8) NOT NULL ,
ODATE DATETIME DEFAULT(GETDATE()),
FOREIGN KEY (CID) REFERENCES Customer(CID)
);
CREATE TABLE Orderdetail
(ONO CHAR(10) NOT NULL,
PNO CHAR(6) NOT NULL,
PPR FLOAT(8) NOT NULL,
NUM INT(4) NOT NULL,
QISHU INT(4) NOT NULL,
TOTAL FLOAT(8) NOT NULL,
PRIMARY KEY (ONO,PNO),
FOREIGN KEY (ONO) REFERENCES Oder(ONO),
FOREIGN KEY(PNO) REFERENCES Paper(PNO)
);
6.2数据库分离和恢复方案
6.2.1分离数据库
在企业管理器中右击需要备份的数据库,选择“所有任务”,“分离数据库”,执行分离操作,之后可进行拷贝数据库MDF文件和LDF文件。
6.2.2恢复数据库
在企业管理器的控制台树中选择“数据库”节点,右击,“所有任务”,“附加数据库”,找到待恢复数据库的MDF文件,确定。
7.应用界面设计和应用程序编码
7.1用户界面设计
本系统的用户界面用Java Swing编写,主要由一个登陆界面,一个主界面,多个子功能实现界面和多个辅助对话框组成。主界面集合系统主要基本功能按键,子功能实现界面和辅助对话框负责采集用户输入信息和做基本的信息处理
图7.1登陆界面
图7.2主界面
7.2类文件功能描述
NO.
类名
类
功能
1
LoginFrame
Frame
登陆界面类,实现登陆功能
2
MainFrame
Frame
主界面类,显示主界面,可连接到其他各个子功能界面
3
PaperFrame
Frame
报刊管理类,实现报刊管理界面,及部分子功能
4
OrderFrame
Frame
订单管理类,实现订单管理界面,及部分子功能
5
CustomerFrame
Frame
用户管理类,实现用户管理界面,及部分子功能
6
AdminFrame
Frame
账户管理类,实现修改账户密码、添加管理员和删除管理员
7
StatsFrame
Frame
数据统计类,统计各种报刊的汇总订阅情况并列表显示
8
addCustomer
Dialog
添加客户类,实现添加客户功能
9
addOrder
Dialog
添加订单类,实现添加订单功能
10
addPaper
Dialog
添加报刊类,实现添加报刊功能
11
ConnectDB
辅助类
实现数据库连接功能
12
deleteCutomer
Dialog
删除客户类,实现删除客户功能
13
deleteOrder
Dialog
删除订单类,实现删除订单功能
14
deletePaper
Dialog
删除报刊类,实现删除报刊功能
15
updateCustomer
Dialog
修改客户类,实现修改客户信息功能
16
updateOrder
Dialog
查看订单详情类,实现修改订单功能,可以删除和修改订单项
17
updatePaper
Dialog
修改报刊类,实现修改报刊信息功能
7.3主要代码分析
//数据库连接类,实现与数据库的连接,并能返回一个Statement对象
//采用JDBC方式,需要加载SQLServer for JDBC Driver(驱动)
public class ConnectDB {
String driverclass = "com.microsoft.jdbc.sqlserver.SQLServerDriver";
String url = "jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=DingBao";
String userName = "sa";
String userPassword = "sa";
private Connection con;
public Statement stmt;
public Statement Connect(){
try{
Class.forName(driverclass);
con = DriverManager.getConnection(url,userName,userPassword);
stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
}
catch(Exception e){
e.printStackTrace();
}
return stmt;
}
}}
//添加客户模块,实现添加客户信息功能
//下程序为“添加”按钮所执行的添加客户信息功能的实现
final JButton button = new JButton();
button.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent e) {
if(textField.getText().trim().length()!=0&&
textField_1.getText().trim().length()!=0&&
textField_2.getText().trim().length()!=0&&
textField_3.getText().trim().length()!=0&&
textField_4.getText().trim().length()!=0){
if(textField.getText().trim().length()>8){
JOptionPane.showMessageDialog(null,"客户ID过长,请重新输入!\n客户ID不能超过8位数","错误!",JOptionPane.ERROR_MESSAGE);
}
else{
String sql = "select * from Customer where CID='"+textField.getText()+"'";
try{
Statement stmt = new ConnectDB().Connect();
ResultSet rs = stmt.executeQuery(sql);
if(rs.next()){
JOptionPane.showMessageDialog(null,"客户ID已存在,请重新输入!","错误!",JOptionPane.ERROR_MESSAGE);
}
else{
String sql1 = "insert into Customer values('" +
textField.getText().trim()+"','" +
textField_1.getText().trim()+"','"+
textField_2.getText().trim()+"','"+
textField_3.getText().trim()+"','"+
textField_4.getText().trim()+"')";
try{
Statement stmt1 = new ConnectDB().Connect();
stmt1.executeUpdate(sql1);
JOptionPane.showMessageDialog(null,"添加客户成功!","成功!",JOptionPane.INFORMATION_MESSAGE);
textField.setText(null);
textField_1.setText(null);
textField_2.setText(null);
textField_3.setText(null);
textField_4.setText(null);
}catch(Exception e3){
e3.printStackTrace();
}
}
}catch (Exception e2){
e2.printStackTrace();
}
}
}
else{
JOptionPane.showMessageDialog(null,"输入的客户信息不完整,添加失败!","错误!",JOptionPane.ERROR_MESSAGE);
}
}
});
button.setText("添加");
button.setBounds(22, 167, 72, 28);
getContentPane().add(button);
//添加订单模块,实现添加订单功能,一个订单可以选择多个报刊
//下程序忽略了界面实现部分,只给出了实现主要功能的部分
button.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent e) {//查询
try{
String sql = "select CNA from Customer where CID='"+textField.getText().trim()+"'";
Statement stmt = new ConnectDB().Connect();
ResultSet rs = stmt.executeQuery(sql);
if(rs.next()){
textField_1.setText(rs.getString("CNA").trim());
textField_2.setEditable(true);
textField_3.setEditable(true);
combobox.setEnabled(true);
button_1.setEnabled(true);
button_2.setEnabled(true);
String sql1 = "insert into Oder (ONO,CID) values('"+label_2.getText().trim()+"','"+textField.getText().trim()+"')";
sqls.add(sql1);
}
else{
JOptionPane.showMessageDialog(null,"输入的客户ID不存在!","错误!",JOptionPane.ERROR_MESSAGE);
}
}catch (Exception e1){
e1.printStackTrace();
}
}
});
button_1.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent e) {//添加报纸
textField.setEditable(false);
button.setEnabled(false);
if(textField_2.getText().trim().length()!=0&&textField_3.getText().trim().length()!=0){
try{
String sql = "select * from Paper where PNO='"+combobox.getSelectedItem().toString().trim()+"'";
Statement stmt = new ConnectDB().Connect();
ResultSet rs = stmt.executeQuery(sql);
rs.next();
price = rs.getFloat("PPR");
num = Integer.parseInt(textField_2.getText().trim());
qishu = Integer.parseInt(textField_3.getText().trim());
total = price * num * qishu;
sum += total;
sql = "insert into Orderdetail (ONO,PNO,PPR,NUM,QISHU,TOTAL) values('" +
label_2.getText().trim()+"','" +
combobox.getSelectedItem().toString().trim()+"'," +
price+"," +
num+"," +
qishu+"," +
total+")";
sqls.addElement(sql);
Vector<String> vt = new Vector<String>();
vt.addElement(combobox.getSelectedItem().toString().trim());
vt.addElement(rs.getString("PNA").trim());
vt.addElement(""+price);
vt.addElement(""+num);
vt.addElement(""+qishu);
vt.addElement(""+total);
rows.add(vt);
DefaultTableModel model = new DefaultTableModel(rows,columnHeads);
table.setModel(model);
label_9.setText(""+sum);
combobox.removeItem(combobox.getSelectedItem());
}catch (SQLException e3){
e3.printStackTrace();
}catch (NumberFormatException exc){
JOptionPane.showMessageDialog(null, "请在 订阅份数 和 订阅期数 输入正确的数字","错误!", JOptionPane.ERROR_MESSAGE);
}
}
else{
JOptionPane.showMessageDialog(null, "请输入 订阅份数 和 订阅期数","错误!", JOptionPane.ERROR_MESSAGE);
}
}
});
button_2.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent e) {//提交订单
if(sqls.size()>1){
int answer = JOptionPane.showConfirmDialog(null, "一共需要支付货款: "+ sum + " 元\n是否支付?", "确认支付",
JOptionPane.YES_NO_CANCEL_OPTION);
if(answer==JOptionPane.YES_OPTION){
try {
Statement stmt = new ConnectDB().Connect();
for (int i = 0; i < sqls.size(); i++) {
stmt.executeUpdate(sqls.get(i));
}
dispose();
JOptionPane.showMessageDialog(null, "添加订单成功!","成功!",JOptionPane.INFORMATION_MESSAGE);
}catch (SQLException e5){
e5.printStackTrace();
}
}else if(answer == JOptionPane.NO_OPTION){
展开阅读全文