当前位置:文档之家› 课程设计-报刊订阅管理系统

课程设计-报刊订阅管理系统

软件工程课程设计报告目录1.开发环境和相关技术介绍1.1开发环境 (3)1.2相关技术介绍 (3)2.需求分析2.1系统需求和功能 (3)2.2数据字典 (4)2.2.1数据结构 (4)2.2.2数据项 (4)2.2.3数据流 (5)2.3安全性要求 (5)2.4一致性要求 (5)2.5完整性要求 (5)3面向对象分析3.1面向对象分析 (5)3.2系统的结构图 (8)4.数据库实施4.1数据库创建 (8)4.1.1各数据表说明 (8)4.1.2数据库创建 (9)4.2数据库备份和恢复方案 (10)4.2.1应用辅助工具进行备份和恢复 (10)4.2.2分离数据库法 (10)4.3用户界面设计和应用程序编码 (10)4.3.1用户界面设计 (10)4.3.2类文件功能描述 (11)4.3.3主要代码分析 (11)5.系统测试方案和测试报告5.1测试方案 (16)5.2测试过程 (16)5.2.1登陆测试 (16)5.2.2目录管理功能测试 (17)5.2.3订户管理功能测试 (20)5.2.4订单管理功能测试 (21)5.2.5统计查询测试 (23)6.完成情况和总结6.1完成情况 (24)6.2总结 (24)7.参考文献1.开发环境和相关技术介绍1.1开发环境系统结构:C/S结构数据库系统:Microsoft SQL Server 2000 sp3宿主语言:JAVA数据库连接方式:JDBC连接方式开发工具:Eclipse 3.21.2相关技术介绍Microsoft SQL Server 2000数据库管理系统是微软公司研制开发的关系型数据库管理系统。

该系统支持并扩展了SQL语言标准,可以运用标准SQL语句对数据进行操作,也可以使用功能强大的GUI工具进行灵活的数据管理。

同时,系统还提供功能完善的API,可以在应用程序中调用这些API来实现与数据库系统的连接以及相关数据的操作。

sp3是该系统的一个版本号,只有sp3以上的SQL 2000系统才能够支持纯JDBC连接方式。

Eclipse:功能强大的应用程序开发工具,主要支持基于Java语言的各种开发项目。

灵活的Plun-in功能,可以根据具体需要安装各种插件。

JDBC连接方式:Java与数据库系统的一种连接方式,Java程序使用JDBC API 与数据库进行通信,并用它操作数据库中的数据。

JDBC API使Java程序与具体数据库系统独立开来,保证了Java程序高度的可移植性。

2.需求分析2.1系统需求和功能设计一个报刊订阅应用系统,使系统满足以下功能和需求:1)a一个订户可订多种报刊;一种报刊可被多个用户订阅;订单只能订阅现有报刊目录内容;b投递时,必须根据订单的情况进行投递,不得超出订单的订阅品种、数量;2)、系统功能包括:a订户管理:订户添加、修改、删除;b 目录管理:目录添加、修改、删除;c订单管理:完成订户订阅数据的管理(包括添加、修改、删除);d 订单查询:按订户或者订单号查询订单详细情况;e统计查询:按报刊目录统计各类报刊的订阅数量及金额;f表单生成:根据统计查询结果导出统计信息到文件(.xl2.2数据字典2.2.1数据结构管理员用户=管理员帐户+管理员密码订户=订户编号+订户名+联系电话+联系地址目录=目录编号+目录名+单价+批注信息订单=订单号+订户编号+下订日期订单细节=订单号+目录编号+订阅数量+订阅期数+单价+总价(注:为保证订单确定后价格不随目录单价变动,订单细节中应该有独立的单价来记录下订时目录的单价)2.2.2数据项2.2.3数据流2.3安全性要求访问数据库时需要输入登陆帐号和密码。

在数据库内设有管理员表,登陆系统时会要求输入管理员帐号和密码。

登陆模块根据输入帐号和密码查管理员表,查到匹配记录则允许其登陆系统。

管理员帐号和密码可以在系统中添加和修改。

2.4一致性要求在管理系统相关的表之间,有较强的关联性。

为了实现一致性的需求,各个表之间均建立起了相应的一致性约束。

2.5完整性要求根据报刊订阅管理系统的要求,为保持数据的完整性,采用了数据库的事务机制,防止出现操作故障引起的数据不一致。

3面向对象分析3.1 面向对象分析设计报刊订阅系统,主要的目的是使得用户在订阅是能跟回家的方便快捷同时也使得报刊提供商能更加有效的管理企业的销售状况。

同时面向对象分析使得人员关注理解系统需要建立的内容,从而产生一个准确的完整的一致的和可验证的系统模型。

管理员表(Administrator):用于存放管理员的数据记录,包括数据项:管理员名、密码。

●部门表(Department):用来存放部门的相关记录,包括数据项:部门号,部门名。

●用户表(Consumer):用于存放注册用户的记录,包括数据项:用户账号、密码、真实姓名、身份证号、联系电话,联系地址,部门号(和部门表有关)等。

●报刊信息表(magazine):用于存放报刊记录,包括数据项:报刊代号、报刊名称、出版报社、出版周期、季度报价、内容介绍、分类编号(和报刊类别表有关)等。

订单表(subscribe):用于存放用户下达的订阅报刊的基本信息,包括数据项:订单编号用户编号(用户表的主码)、报刊代号(报刊信息表的主码)、订阅份数、订阅月数等。

用例图:由上面的分析需能够确定系统用例图:类图:在根据已定义的对象类及其联系,以及对象类的多重性、角色、导航等性质,可以画出对象类图 ,使用对象图的目的是分析系统的瞬间状态,以便进一步了解系统的结构和行为。

分析对象模型:也同时可以确定所有实体之间的E-R 图:处理管理员订单用户订制拥有订阅包含部门报刊报刊类别用户帐号真实姓名密码身份证号联系电话联系地址部门号部门号部门名称管理员名密码分类编号分类名称报刊代号报刊名称出版报社出版周期内容介绍季度订价分类编号订单编号用户账号报刊代号订阅份数订阅月数1M1M 1MMNM1图3.1 报刊订阅管理系统E-R 图3.2系统结构图图4.1 系统结构图4.数据库实施4.1数据库创建4.1.1各数据表说明表4.1 数据表描述表4.1.2数据库创建在Microsoft SQL Server 2000的企业管理器中完成数据库和数据表的创建CREATE TABLE [dbo].[Customer] ([Cid] [varchar] (10) COLLATE Chinese_PRC_CI_AS NOT NULL ,[Cname] [varchar] (20) COLLATE Chinese_PRC_CI_AS NULL ,[Phone] [varchar] (15) COLLATE Chinese_PRC_CI_AS NULL ,[Address] [varchar] (50) COLLATE Chinese_PRC_CI_AS NOT NULL ) ON [PRIMARY]GOCREATE TABLE [dbo].[Login] ([UName] [varchar] (20) COLLATE Chinese_PRC_CI_AS NOT NULL , [UPassword] [varchar] (20) COLLATE Chinese_PRC_CI_AS NOT NULL ) ON [PRIMARY]GOCREATE TABLE [dbo].[Diretory] ([Did] [varchar] (10) COLLATE Chinese_PRC_CI_AS NOT NULL ,[Dname] [varchar] (20) COLLATE Chinese_PRC_CI_AS NULL ,[UnitPrice] [float] NOT NULL ,[Ifo] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL) ON [PRIMARY]GOCREATE TABLE [dbo].[Order] ([Ono] [varchar] (10) COLLATE Chinese_PRC_CI_AS NOT NULL ,[Cid] [varchar] (10) COLLATE Chinese_PRC_CI_AS NOT NULL ,[Odate] [datetime] NULL) ON [PRIMARY]GOCREATE TABLE [dbo].[OrderDetail] ([Ono] [varchar] (10) COLLATE Chinese_PRC_CI_AS NOT NULL ,[Did] [varchar] (10) COLLATE Chinese_PRC_CI_AS NOT NULL ,[Quantity] [int] NOT NULL ,[QiShu] [int] NOT NULL ,[UnitPrice] [float] NOT NULL ,[Total] [float] NULL) ON [PRIMARY]GO4.2数据库备份和恢复方案4.2.1应用辅助工具进行备份和恢复应用数据库辅助工具(如sqlbackuptools…)进行备份,选择所需要备份的数据库和目标地址即可进行数据备份,恢复数据库只需要指定备份文件和需要恢复的数据库即可进行数据恢复。

4.2.2分离数据库法在企业管理器中右击需要备份的数据库,选择“所有任务”,“分离数据库”,执行分析操作,拷贝数据库MDF文件和LDF文件。

恢复方案:在企业管理器的控制台树中选择“数据库”节点,右击,“所有任务”,“附加数据库”,找到待恢复数据库的MDF文件,确定。

4.3用户界面设计和应用程序编码4.3.1用户界面设计本系统的用户界面用Java Swing编写,主要由1个主界面Newspaper.java 和10个辅助对话框组成。

主界面集合系统主要基本功能按键,辅助对话框负责采集用户输入信息和做基本的信息处理。

用户界面4.3.2类文件功能描述4.3.3主要代码分析//----------------------------------------------------------------------------- //所属类:Utilities//功能:取得应用程序与数据库系统的连接public static void getConnection() throws Exception {Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver").newInstance();//加载驱动程序String url ="jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=Newspaper";String user = "sa";String password = "";conn = DriverManager.getConnection(url, user, password);//取得连接stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);//创建语句conn2 = DriverManager.getConnection(url, user, password);stmt2 = conn2.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);}//----------------------------------------------------------------------------- //所属类:Utilities//功能:完成查询结果的表格显示public static void displayResultSet(JTable table, ResultSet rs)throws SQLException {rs.beforeFirst();// 指针移到结果集第一条记录前面boolean moreRecords = rs.next();if (!moreRecords) {// 如果没有记录,则提示一条消息JOptionPane.showMessageDialog(table, "无相关记录", "Check your input!", JOptionPane.ERROR_MESSAGE);return;}Vector columnHeads = new Vector();// 用于存储表格字段Vector rows = new Vector();// 用于存储记录行try {// 获取字段的名称ResultSetMetaData rsmd = rs.getMetaData();for (int i = 1; i <= rsmd.getColumnCount(); ++i)columnHeads.addElement(rsmd.getColumnName(i));do {// 获取记录集rows.addElement(getNextRow(rs, rsmd));} while (rs.next());// 建立相应的TableModel,并将TableModel应用到table中显示出来DefaultTableModel model = new DefaultTableModel(rows, columnHeads);table.setModel(model);return;} catch (SQLException sqlex) {sqlex.printStackTrace();}}//-----------------------------------------------------------------------------//所属类:Utilities//功能:被displayResultSet(JTable table, ResultSet rs)调用, 返回一个记录行private static Vector getNextRow(ResultSet rs, ResultSetMetaData rsmd)throws SQLException {Vector<String> currentRow = new Vector<String>();for (int i = 1; i <= rsmd.getColumnCount(); ++i)currentRow.addElement(rs.getString(i));return currentRow; // 返回一条记录}//----------------------------------------------------------------------------- //所属类:Utilities//功能:创建空白EXCEL文件,并将统计查询结果导出到该EXCEL文件//说明:使用到org.apache的POI包,表示感谢public static boolean outPut(ResultSet rs, File file) {if (rs == null)return false;try {HSSFWorkbook wb = new HSSFWorkbook();HSSFSheet sheet = wb.createSheet("first sheet");sheet.setDefaultColumnWidth((short) 20);ResultSetMetaData metadata = rs.getMetaData();int columnCount = metadata.getColumnCount();// 获取属性列数HSSFRow row = sheet.createRow((short) 0);for (int i = 1; i <= columnCount; i++) {// 填写表格列名row.createCell((short) (i - 1)).setCellValue(metadata.getColumnName(i));}// 按行填写记录rs.beforeFirst();short counter = 1;while (rs.next()) {row = sheet.createRow(counter++);for (int i = 1; i <= columnCount; i++) {row.createCell((short) (i - 1)).setCellValue(String.valueOf(rs.getObject(i)));}}FileOutputStream fileOut = new FileOutputStream(file);wb.write(fileOut);// 结果输出到文件fileOut.close();// 关闭输出流} catch (Exception exc) {exc.printStackTrace();}return true;}}//----------------------------------------------------------------------------- //所属类:Newspaper//功能:统计查询final JMenuItem menuItem_9 = new JMenuItem();menuItem_9.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {String sql = "SELECT Diretory.Did AS 刊物编号,Dname AS 刊物名称,"+ "SUM(Quantity*QiShu) AS 总订阅数,SUM(Total) AS 总金额"+ " FROM Diretory LEFT JOIN OrderDetail ON(OrderDetail.Did=Diretory.Did) "+ " GROUP BY Diretory.Did,Diretory.Dname "+ " ORDER BY SUM(Total) DESC";try {Utilities.rs= Utilities.stmt.executeQuery(sql);// 执行统计查询Utilities.displayResultSet(table, Utilities.rs);//显示查询结果} catch (SQLException exc) {exc.printStackTrace();}}});//-----------------------------------------------------------------------------//所属类:UserCreateDlg//功能:创建新用户final JButton button = new JButton();button.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {if (textField_1.getText().trim().length() != 0&& textField_2.getText().trim().length() != 0&& textField_3.getText().trim().length() != 0) {String sql = "INSERT INTO Customer(Cid,Cname,Phone,Address) "+ "VALUES('"+ textField.getText().trim()+ "','"+ textField_1.getText().trim()+ "','"+ textField_2.getText().trim()+ "','"+ textField_3.getText().trim() + "')";try {Utilities.stmt.executeUpdate(sql);// 执行数据行插入JOptionPane.showMessageDialog(dialog, "用户:"+ textField_1.getText() + "添加成功\nID:"+ textField.getText(), "Success !",RMATION_MESSAGE);dispose();} catch (SQLException exc) {exc.printStackTrace();}} else {JOptionPane.showMessageDialog(dialog, "信息不全,无法添加","Check your input !", JOptionPane.ERROR_MESSAGE);}}});//-----------------------------------------------------------------------------//所属类:UserModifyDlg//功能:用户信息更新修改button_2 = new JButton();button_2.setEnabled(false);button_2.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {if (textField_1.getText().trim().length() != 0&& textField_2.getText().trim().length() != 0&& textField_3.getText().trim().length() != 0) {try {Utilities.rs.updateString("Cname", textField_1.getText().trim());Utilities.rs.updateString("Phone", textField_2.getText().trim());Utilities.rs.updateString("Address", textField_3.getText().trim());Utilities.rs.updateRow();// 更新数据行JOptionPane.showMessageDialog(dialog, "更新成功!","Success !", RMATION_MESSAGE);dispose();} catch (SQLException exc) {}} else {JOptionPane.showMessageDialog(dialog, "信息不全,无法修改","Check your input !", JOptionPane.ERROR_MESSAGE);}}});//-----------------------------------------------------------------------------//所属类:BookingDlg//功能:读取订单数据,向系统添加订单button_1 = new JButton();button_1.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {try {String sql = "SELECT UnitPrice FROM Diretory WHERE Did='"+ comboBox.getSelectedItem() + "'";Utilities.rs = Utilities.stmt.executeQuery(sql);// 查询当前选择目录刊物的单价if (Utilities.rs.next()) {unitPrice = Utilities.rs.getFloat("UnitPrice");quantity = Integer.parseInt(textField_1.getText());qishu = Integer.parseInt(textField_2.getText());total = unitPrice * quantity * qishu;sum += total;s ql = "INSERT INTO OrderDetail (ONo, Did, Quantity, QiShu,UnitPrice, total)"+ "VALUES('"+ label_2.getText()+ "','"+ comboBox.getSelectedItem()+ "',"+ quantity+ ","+ qishu+ ","+ unitPrice+ ","+ total+ ")";sqls.add(sql);// 寄存订单细节插入语句comboBox.removeItem(comboBox.getSelectedItem());// 将已选择目录从下拉选择框中移除(一个订单不能有两个目录相同的订单项) }} catch (SQLException exc) {exc.printStackTrace();} catch (NumberFormatException exc) {JOptionPane.showMessageDialog(dialog, "错误数字输入","Check again !", JOptionPane.ERROR_MESSAGE);}}});button_1.setEnabled(false);button_1.setText("添加订单项");panel_1.add(button_1);button_2 = new JButton();button_2.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {if (sqls.size() > 1) {// 容器第一个空间放插入Order的sql语句,其它空间放插入OrderDetail的sql语句// sqls.size()==1表示只有一张空订单,不予插入int ans = JOptionPane.showConfirmDialog(dialog, "一共需要支付订金:"+ sum + "元\nContinue?", "We need your money",JOptionPane.YES_NO_CANCEL_OPTION);if (ans == JOptionPane.YES_OPTION) {try {for (int i = 0; i < sqls.size(); i++) {// 顺序取出sql语句,完成订单添加插入Utilities.stmt.executeUpdate(sqls.get(i));// 执行插入更新语句}dispose();JOptionPane.showMessageDialog(dialog, "订单添加成功!","Success!",RMATION_MESSAGE);} catch (SQLException exc) {exc.printStackTrace();}} else if (ans == JOptionPane.NO_OPTION) {dispose();}} else {JOptionPane.showMessageDialog(dialog,"订单为空,不能提交,请选择需要订阅的期刊", "Check again !",JOptionPane.ERROR_MESSAGE);}}});button_2.setEnabled(false);button_2.setText("提交订单");panel_1.add(button_2);5.系统测试方案和测试报告5.1测试方案由于系统规模较小,所以没有安排单独的白盒测试,而是相应地将这部分测试归并到系统编码过程中。

相关主题