第一次优化后---学生管理系统(层次分明的设计)

来源:互联网 发布:python 免费 ide 编辑:程序博客网 时间:2024/05/05 09:30

程序源代码:http://download.csdn.net/detail/u012332962/6493517(仅供参考)

在上周,个人学习java的路上,写了一个可以连接数据库,从数据库中拿去数据的学生管理系统,但鉴于动能过于简单,同时时写学来的程序没有一个调理性,导致代码实在看着就是一个词形容:惨不忍睹,丝毫条理性都没有,所以几个一个星期的空余时间的努力,我又做出了里一个学生选课管理系统,功能相近,只是优化了整个设计过程,利用了老师说的结构,数据,与视图的分析方法,个人不知道是不是传说中的MVC默认,但是整个开发过程,个人觉得比第一次设计的时候,思路清楚了很多,各种设计都能顺利设计出来,更重功能的响应都有了一个统一了解

本次设计过程将数据库的操作与界面实现了很好的分离,目前个人还不怎么了解为什么不能在主界面程序中包含有数据库的操作语句(学习MLDN的java开发实战经典中李兴华在最后一节的设计课上强调了这一点),但觉得这个应该是为了数据操作的安全考虑

本次设计,因为要数据与操作,视图进行分离所以数据库进行了进一步的了解深化,但主要的功能还是一样的,只是深入理解了一下,一个软件开发设计的一个整体过程;

数据库的简单设计;

建立数据库 CREATE DATABASE MANAGER; 建立用户表:CREATE TABLE `user` (  `username` varchar(20) NOT NULL,  `password` varchar(16) NOT NULL DEFAULT '111111',  `admin` tinyint(1) NOT NULL DEFAULT '0', //是否有管理员权限  PRIMARY KEY (`username`)) 建立学生信息表;CREATE TABLE `student` (  `username` int(8) NOT NULL,  `name` varchar(20) NOT NULL,  `sex` tinyint(1) unsigned zerofill NOT NULL,  `birthday` date DEFAULT NULL,  PRIMARY KEY (`username`))建立课程表:CREATE TABLE `course` (  `id` int(8) unsigned NOT NULL AUTO_INCREMENT,  `cname` varchar(20) NOT NULL,  `credit` tinyint(2) NOT NULL DEFAULT '2',  `room` varchar(20) DEFAULT 'E307',  `time` tinyint(1) NOT NULL,  PRIMARY KEY (`id`))建立学生选课表:CREATE TABLE `studentcourse` (  `username` int(8) NOT NULL,  `id1` int(8) DEFAULT NULL,  `id2` int(8) DEFAULT NULL,  `count` int(1) NOT NULL DEFAULT '0',  PRIMARY KEY (`username`))建立出发器:添加或删除用户的时候使用:CREATE    TRIGGER `delete_student` BEFORE DELETE ON `student`     FOR EACH ROW BEGINDELETE FROM users WHERE users.username = old.username;    END;CREATE    TRIGGER `insert_student` BEFORE INSERT ON `student`     FOR EACH ROW BEGININSERT INTO users(username) VALUES(new.username);    END;    

下次更新会更新一个manager类主要对数据库内的人员及数据进行增,删,改,查,对数据哭内部的数据进行操作

程序的见面进行了改进(上次那个版本实在太惨不忍睹了,传说中差到极点的UI设计了)

大致地给大家看一下主要的类设计;

几个包作用的说明,本次设计的过程可以从包名中体验出来,因为这些包名就很好的解释了,进过”MVC”设计之后的功能作用(对比上次的设计,是不是光从报名上就可以知道,整个设计的过程没有半点的犹豫,对整个功能的需求及用途都有了一个大致的设计方向)

下面对这些类进行详细地列出(因为本次作品是对上一个作品的一个设计过程的优化,而且这行优化都在代码中,所以不再进行过多的陈诉,有空就看看,指点指点吧,我是一个善于接受批评的人哦,我要在自己千疮百孔的身体上走过,升华自己!

一,隔离出来的数据(package com.rainplus.data;)1.public class Course2public class Student3. public class User 4. public class StudentCourse二,独立出来的界面(package com.rainplus.frame)1 class LoginFrame extends JFrame2 public class MainFrame extends JFrame3manager类在下次更新时实现三,拥有自主权的数据库操作(package com.rainplus.DBOperate;)1 public class DBOperate implements IDBOperate2 public interface IDBOperate {四,数据库的链接(package com.rainplus.jdbc;)1 public class ConnectDB一,隔离出来的数据(package com.rainplus.data;)1 public class Course {private String id;private String cname;private String credit;private String room;private String time;/*此处省去getter and setter**/}2 public class Student {private String username;private String name;private String sex;private String birthday;private String college;/*此处省去getter and setter**/}3. public class StudentCourse {private String username;private String id1;private String id2;private int count;/*此处省去getter and setter**/}4. public class User {private String username;private String password;private String admin;/*此处省去getter and setter**/}二,独立出来的界面(package com.rainplus.frame)1package com.rainplus.frame;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JOptionPane;import javax.swing.JPanel;import javax.swing.JPasswordField;import javax.swing.JTextField;import com.rainplus.DBOperate.DBOperate;import com.rainplus.data.User;class LoginFrame extends JFrame {private JPanel content;private JLabel userLabel;private JLabel passwordLabel;private JPasswordField passwordField;private JTextField userNameField;private JButton loginButton;private JButton exitButton;private JButton adminButton;private DBOperate operate;private User user;private final String ADMIN = "1";public LoginFrame() {super("优化学生选课系统");setSize(250, 200);setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);content = new JPanel();content.setLayout(null);add(content);userLabel = new JLabel("学号:");userLabel.setBounds(30, 30, 40, 20);content.add(userLabel);userNameField = new JTextField("11046201");userNameField.setBounds(80, 30, 120, 20);content.add(userNameField);passwordLabel = new JLabel("密码:");passwordLabel.setBounds(30, 60, 40, 20);content.add(passwordLabel);passwordField = new JPasswordField();passwordField.setBounds(80, 60, 120, 20);content.add(passwordField);loginButton = new JButton("登录");loginButton.setBounds(30, 90, 80, 20);loginButton.addActionListener(new buttonListenner());content.add(loginButton);exitButton = new JButton("退出");exitButton.setBounds(120, 90, 80, 20);exitButton.addActionListener(new buttonListenner());content.add(exitButton);adminButton = new JButton("管理员身份登录");adminButton.setBounds(30, 120, 170, 20);adminButton.addActionListener(new buttonListenner());content.add(adminButton);/* 设置窗体可见和居中 */setVisible(true);setLocationRelativeTo(null);}/* 获取登录用户信息内容 */public String[] getText() {String[] strings = new String[2];strings[0] = userNameField.getText();strings[1] = new String(passwordField.getPassword());return strings;}public static void main(String[] args) {new LoginFrame();}class buttonListenner implements ActionListener {/* * (非 Javadoc) *  * @see * java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent *  * ) */@Overridepublic void actionPerformed(ActionEvent e) {operate=new DBOperate();if (exitButton==e.getSource()) {System.exit(0);}if (loginButton==e.getSource()) {userLogin();}if (adminButton==e.getSource()) {adminLogin();}}/** *  */private void adminLogin() {String[] strings = getText();user=operate.doReadUser(strings[0]);if (null!=user) {if (user.getAdmin().equals(ADMIN)) {if (user.getPassword().equals(strings[1])) {new ManagerFrame(user, operate);dispose();}else {JOptionPane.showMessageDialog(null, "登录密码错误!");}}else {JOptionPane.showMessageDialog(null, "您不是管理员身份!");}}else {JOptionPane.showMessageDialog(null, "没有这个用户!");}}/** * @author Rainplus */private void userLogin() {String[] strings = getText();user=operate.doReadUser(strings[0]);if (null!=user) {if (user.getPassword().equals(strings[1])) {new MainFrame(user, operate);dispose();}else {JOptionPane.showMessageDialog(null, "登录密码错误!");}}else {JOptionPane.showMessageDialog(null, "没有这个用户!");}}}}2package com.rainplus.frame;import java.awt.BorderLayout;import java.awt.Component;import java.awt.GridLayout;import java.awt.event.MouseAdapter;import java.awt.event.MouseEvent;import java.util.List;import javax.swing.DefaultCellEditor;import javax.swing.JCheckBox;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JOptionPane;import javax.swing.JPanel;import javax.swing.JScrollPane;import javax.swing.JSplitPane;import javax.swing.JTable;import javax.swing.table.DefaultTableModel;import javax.swing.table.TableCellRenderer;import javax.swing.table.TableColumnModel;import com.rainplus.DBOperate.DBOperate;import com.rainplus.data.Student;import com.rainplus.data.StudentCourse;import com.rainplus.data.User;import com.rainplus.data.Course;public class MainFrame extends JFrame {private JLabel[] userlabel; // 用户信息;private JTable userCoursetable;// 用户已经选择的课程;private JTable coursesTable;// 所有可以选择的课程;private DBOperate operate;private User user;public MainFrame(User user, DBOperate operate) {super("优化学生选课系统");this.setSize(625, 400);this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);this.operate = operate;this.user = user;JSplitPane split_h = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);split_h.setDividerLocation(140);JSplitPane split_v = new JSplitPane(JSplitPane.VERTICAL_SPLIT);split_v.setDividerLocation(120);/* 用户信息: */JPanel userInfor = new JPanel(new GridLayout(5, 2));userlabel = new JLabel[5];for (int i = 0; i < userlabel.length; i++) {userlabel[i] = new JLabel();}userInfor.add(new JLabel("  用户名:"));userInfor.add(userlabel[0]);userInfor.add(new JLabel("  姓    名:"));userInfor.add(userlabel[1]);userInfor.add(new JLabel("  性    别:"));userInfor.add(userlabel[2]);userInfor.add(new JLabel("  生    日:"));userInfor.add(userlabel[3]);userInfor.add(new JLabel("  学    院:"));userInfor.add(userlabel[4]);setStudentInfor(user, operate, userlabel);split_v.add(userInfor);/* 以选择课程信息 */JPanel userCourse = new JPanel(new BorderLayout());userCourse.add(new JLabel("  已选则课程:"), BorderLayout.NORTH);userCoursetable = setStudentCourse(user, operate);userCourse.add(new JScrollPane(userCoursetable), BorderLayout.CENTER);split_v.add(userCourse);split_h.add(split_v);/* 所有课表信息 */coursesTable = setCourse(user, operate);JPanel coursePanel = new JPanel();coursePanel.add(new JScrollPane(coursesTable));split_h.add(coursePanel);/* 给折现事件添加事件监听 */coursesTable.addMouseListener(new SelecteLisener());this.getContentPane().add(split_h);this.setVisible(true);this.setLocationRelativeTo(null);}class SelecteLisener extends MouseAdapter {@Overridepublic void mouseClicked(MouseEvent e) {int rowIndex = coursesTable.getSelectedRow();int colIndex = coursesTable.getSelectedColumn();if (colIndex == 5) {Object selecteId = coursesTable.getValueAt(rowIndex, 0);/* * 判断选课状态1已选,2没选 已选,则退选 没选,则选择 */if ((boolean) coursesTable.getValueAt(rowIndex, colIndex)) {if (JOptionPane.showConfirmDialog(null, "确定选择这一门课程!") == 0) {selecteCourse(rowIndex, colIndex, selecteId);} else {coursesTable.setValueAt(false, rowIndex, colIndex);}} else {if (JOptionPane.showConfirmDialog(null, "确定取消这一门课程!") == 0) {cancalCourse(rowIndex, colIndex, selecteId);} else {coursesTable.setValueAt(true, rowIndex, colIndex);}}}}/** * @param rowIndex * @param colIndex * @param selecteId */private void cancalCourse(int rowIndex, int colIndex, Object selecteId) {StudentCourse studentCourse = operate.doSelectedCourses(user);if (studentCourse.getId1().equals(selecteId)) {userCoursetable.setValueAt("", 0, 0);userCoursetable.setValueAt("", 0, 1);}if (studentCourse.getId2().equals(selecteId)) {userCoursetable.setValueAt("", 1, 0);userCoursetable.setValueAt("", 1, 1);}if (studentCourse.getId1().equals(selecteId)) {studentCourse.setId1("0");}if (studentCourse.getId2().equals(selecteId)) {studentCourse.setId2("0");}studentCourse.setCount((studentCourse.getCount() - 1));operate.doUpdateStudentCourse(studentCourse);coursesTable.setValueAt(false, rowIndex, colIndex);}/** * @param rowIndex * @param colIndex * @param selecteId * @author Rainplus */private void selecteCourse(int rowIndex, int colIndex, Object selecteId) {StudentCourse studentCourse = operate.doSelectedCourses(user);if (studentCourse.getCount() < 2) {if (studentCourse.getId1().equals("00000000")) {studentCourse.setId1((String) selecteId);} else {if (studentCourse.getId2().equals("00000000")) {studentCourse.setId2((String) selecteId);}}studentCourse.setCount(studentCourse.getCount() + 1);operate.doUpdateStudentCourse(studentCourse);Course course1 = operate.dofindCoures(studentCourse.getId1());Course course2 = operate.dofindCoures(studentCourse.getId2());if (!studentCourse.getId1().equals("00000000")) {userCoursetable.setValueAt(studentCourse.getId1(), 0, 0);userCoursetable.setValueAt(course1.getCname(), 0, 1);}if (!studentCourse.getId2().equals("00000000")) {userCoursetable.setValueAt(studentCourse.getId2(), 1, 0);userCoursetable.setValueAt(course2.getCname(), 1, 1);}} else {JOptionPane.showMessageDialog(null, "只能选择两门课");coursesTable.setValueAt(false, rowIndex, colIndex);}}} class coursesTableCellRenderer extends JCheckBox implementsTableCellRenderer {@Overridepublic Component getTableCellRendererComponent(JTable table,Object value, boolean isSelected, boolean hasFocus, int row,int column) {Boolean b = (Boolean) value;this.setSelected(b.booleanValue());return this;}}public void setStudentInfor(User user, DBOperate operate, JLabel[] userlabel) {Student student = new Student();student = operate.doReadStudent(user);userlabel[0].setText(student.getUsername());userlabel[1].setText(student.getName());userlabel[2].setText(student.getSex());userlabel[3].setText(student.getBirthday());userlabel[4].setText(student.getCollege());}public JTable setStudentCourse(User user, DBOperate operate) {String[] head = { "书        号", "课程名称" };JTable table = null;StudentCourse studentCourse = operate.doSelectedCourses(user);if (null != studentCourse) {String[][] data = new String[2][2];List<Course> list = operate.doReadCourseAll();for (Course course : list) {if (course.getId().equals(studentCourse.getId1())) {data[0][0] = studentCourse.getId1();data[0][1] = course.getCname();}if (course.getId().equals(studentCourse.getId2())) {data[1][0] = studentCourse.getId2();data[1][1] = course.getCname();}}table = new JTable(data, head);} else {table = new JTable(new DefaultTableModel(head, 0));}return table;}public JTable setCourse(User user, DBOperate operate) {List<Course> list = operate.doReadCourseAll();StudentCourse studentCourse = operate.doSelectedCourses(user);int nRows = 0;for (@SuppressWarnings("unused")Course course : list) {nRows++;}Object[][] cObject = new Object[nRows][6];nRows = 0;for (Course course : list) {cObject[nRows][0] = course.getId();cObject[nRows][1] = course.getCname();cObject[nRows][2] = course.getCredit();cObject[nRows][3] = course.getRoom();cObject[nRows][4] = course.getTime();if (cObject[nRows][0].equals(studentCourse.getId1())|| cObject[nRows][0].equals(studentCourse.getId2())) {cObject[nRows][5] = new Boolean(true);} else {cObject[nRows][5] = new Boolean(false);}nRows++;}String[] coursesHead = { "书        号", "课程名称", "学        分","教        室", "上课时间", "选择|退选" };DefaultTableModel tableModel = new DefaultTableModel(cObject,coursesHead) {@Overridepublic boolean isCellEditable(int rowIndex, int columnIndex) {if (columnIndex != 5)return false;// 这个是可以编辑的列return true;}};JTable table = new JTable(tableModel);TableColumnModel tcm = table.getColumnModel();tcm.getColumn(5).setCellEditor(new DefaultCellEditor( new JCheckBox()));tcm.getColumn(5).setCellRenderer(new coursesTableCellRenderer());table.setModel(tableModel);TableColumnModel columnModel = table.getColumnModel();columnModel.getColumn(5).setCellEditor(new DefaultCellEditor(new JCheckBox()));columnModel.getColumn(5).setCellRenderer(new coursesTableCellRenderer());return table;}}3manager 功能待下周完善三,拥有自主权的数据库操作(package com.rainplus.DBOperate;)1package com.rainplus.DBOperate;import java.util.List;import com.rainplus.data.Course;import com.rainplus.data.Student;import com.rainplus.data.StudentCourse;import com.rainplus.data.User;public class DBOperate implements IDBOperatepublic class ConnectDBpublic interface IDBOperate {/* 读取用户消息 */public User doReadUser(String username);/* 返回数据库中的所有课程 */public List<Course> doReadCourseAll();/*return selected course*/public StudentCourse doSelectedCourses(User user);/* 读取用户的信息 */public Student doReadStudent(User user);/* 更新课程 */public boolean  doUpdateStudentCourse(StudentCourse studentCourse);/* 取消课程 *//* 添加学生 */public boolean doInsertStudent(Student student);/* 更新学生 */public boolean doUpdateStudent(String username);/* 删除学生 */public boolean doDeletetStudent(String username);/* 添加课程 */public boolean doInsertCourse(Course course);/* 更新课程 */public boolean doUpdateCourse(Course course);/* 删除课程 */public boolean doDeleteCourse(String id);}2package com.rainplus.DBOperate;import java.sql.Connection;import java.sql.ResultSet;import java.sql.SQLException;import java.util.ArrayList;import java.util.List;import java.sql.PreparedStatement;import javax.swing.JOptionPane;import com.rainplus.data.Course;import com.rainplus.data.Student;import com.rainplus.data.StudentCourse;import com.rainplus.data.User;import com.rainplus.jdbc.ConnectDB;public class DBOperate implements IDBOperate {private ConnectDB connectDB;private Connection connection;public DBOperate() {this.connectDB = new ConnectDB();this.connection = connectDB.getConnection();}/* * (非 Javadoc) *  * @see com.rainplus.DBOperate.IDBOperate#doReadUser(java.lang.String) */@Overridepublic User doReadUser(String username) {String sql = "SELECT users.username,users.password,users.admin FROM users "+ "WHERE users.username=?";User user = new User();PreparedStatement statement = null;try {statement = this.connection.prepareStatement(sql);statement.setString(1, username);ResultSet resultSet = null;resultSet = statement.executeQuery();if (resultSet.next()) {user.setUsername(resultSet.getString(1));user.setPassword(resultSet.getString(2));user.setAdmin(resultSet.getString(3));resultSet.close();} else {user = null;}} catch (SQLException e) {JOptionPane.showMessageDialog(null, "读取用户信息错误!");} finally { // 不管如何抛出,最终肯定是要进行数据库的关闭操作的if (statement != null) {try {statement.close();} catch (Exception e1) {}}}return user;}@Overridepublic List<Course> doReadCourseAll() {List<Course> all = new ArrayList<Course>();PreparedStatement statement = null;String sql = "SELECT course.id,course.cname,course.credit,course.room,course.time"+ " FROM course ";try {statement = this.connection.prepareStatement(sql);ResultSet resultSet = null;resultSet = statement.executeQuery();while (resultSet.next()) {Course course = new Course();course.setId(resultSet.getString(1));course.setCname(resultSet.getString(2));course.setCredit(resultSet.getString(3));course.setRoom(resultSet.getString(4));course.setTime(resultSet.getString(5));all.add(course);}resultSet.close();} catch (SQLException e) {JOptionPane.showMessageDialog(null, "读取所有课程信息错误!");} finally { // 不管如何抛出,最终肯定是要进行数据库的关闭操作的if (statement != null) {try {statement.close();} catch (Exception e1) {}}}return all;}@Overridepublic Student doReadStudent(User user) {Student student = new Student();String sql = "SELECT student.username,student.name,student.sex,student.birthday,student.college "+ "FROM student WHERE student.username=?";PreparedStatement statement = null;try {statement = this.connection.prepareStatement(sql);statement.setString(1, user.getUsername());ResultSet resultSet = null;resultSet = statement.executeQuery();if (resultSet.next()) {student.setUsername(resultSet.getString(1));student.setName(resultSet.getString(2));student.setSex(resultSet.getString(3));student.setBirthday(resultSet.getString(4));student.setCollege(resultSet.getString(5));}resultSet.close();} catch (SQLException e) {JOptionPane.showMessageDialog(null, "读取学生信息错误!");} finally { // 不管如何抛出,最终肯定是要进行数据库的关闭操作的if (statement != null) {try {statement.close();} catch (Exception e1) {}}}return student;}@Overridepublic StudentCourse doSelectedCourses(User user) {StudentCourse studentCourse = null;PreparedStatement statement = null;String sql = "SELECT studentcourse.`username`,studentcourse.`id1`,studentcourse.`id2`,studentcourse.`count` "+ "FROM  studentcourse WHERE studentcourse.`username`=?";try {statement = this.connection.prepareStatement(sql);statement.setString(1, user.getUsername());ResultSet resultSet = null;resultSet = statement.executeQuery();if (null != resultSet) {while (resultSet.next()) {studentCourse = new StudentCourse();studentCourse.setUsername(resultSet.getString(1));studentCourse.setId1(resultSet.getString(2));studentCourse.setId2(resultSet.getString(3));studentCourse.setCount(resultSet.getInt(4));}resultSet.close();}} catch (SQLException e) {JOptionPane.showMessageDialog(null, "学生已选课程信息错误!");e.printStackTrace();} finally { // 不管如何抛出,最终肯定是要进行数据库的关闭操作的if (statement != null) {try {statement.close();} catch (Exception e1) {}}}return studentCourse;}@Overridepublic boolean doUpdateStudentCourse(StudentCourse studentCourse) {PreparedStatement statement = null;String sql = "UPDATE studentcourse  SET studentcourse.id1=? , studentcourse.id2=? ,studentcourse.count=? "+ "WHERE studentcourse.username=?";try {statement = this.connection.prepareStatement(sql);statement.setString(1, studentCourse.getId1());statement.setString(2, studentCourse.getId2());statement.setInt(3, studentCourse.getCount());statement.setString(4, studentCourse.getUsername());statement.executeUpdate();} catch (SQLException e) {// JOptionPane.showMessageDialog(null, "选择课程错误!");e.printStackTrace();} finally { // 不管如何抛出,最终肯定是要进行数据库的关闭操作的if (statement != null) {try {statement.close();} catch (Exception e1) {}}}return false;}@Overridepublic boolean doInsertStudent(Student student) {// TODO 自动生成的方法存根return false;}@Overridepublic boolean doUpdateStudent(String username) {// TODO 自动生成的方法存根return false;}@Overridepublic boolean doDeletetStudent(String username) {// TODO 自动生成的方法存根return false;}@Overridepublic boolean doInsertCourse(Course course) {// TODO 自动生成的方法存根return false;}@Overridepublic boolean doUpdateCourse(Course course) {// TODO 自动生成的方法存根return false;}@Overridepublic boolean doDeleteCourse(String id) {// TODO 自动生成的方法存根return false;}public Course dofindCoures(String id) {Course course = null;List<Course> list = this.doReadCourseAll();for (Course course2 : list) {if (id.equals(course2.getId())) {course=course2;}}return course;}}四,数据库的链接(package com.rainplus.jdbc;)1 package com.rainplus.jdbc;import java.sql.Connection;import java.sql.DriverManager;import java.sql.SQLException;import javax.swing.JOptionPane;public class ConnectDB {private static final String DRIVER = "com.mysql.jdbc.Driver";private static final String DBASE = "jdbc:mysql://localhost/manager";private static final String USER = "root";private static final String PASS = "root";private static Connection con = null;public ConnectDB() {try {Class.forName(DRIVER);} catch (ClassNotFoundException e) {JOptionPane.showMessageDialog(null, "驱动加载失败!");}try {con = DriverManager.getConnection(DBASE, USER, PASS);} catch (SQLException e) {JOptionPane.showMessageDialog(null, "链接数据库失败!");}}/* * 获取链接*/public  Connection getConnection() {return con;}public  void close(){if (null!=con) {try {con.close();} catch (SQLException e) {JOptionPane.showMessageDialog(null, "关闭数据库失败!");}}}}

总结:本次作品第一次深刻体会程序的设计过程需要条理清晰,结构分离,数据独立和操作独立的全部优点