本小节将讲解学生管理系统的代码设计思路及关键代码的实现过程。
24.2.1数据库操作工具
学生管理系统以JDBC为核心技术,因此系统中有多处对数据库的操作。为了更方便的操作数据库,本系统专门定义了操作数据库的工具类DBUtil,连接数据库的参数都以静态属性的形式定义到DBUtil类中,这些参数如下:
static String driverName = "com.mysql.cj.jdbc.Driver";//驱动类
static String url = "jdbc:mysql://localhost:3306/student";//数据库url
static String user = "root";//用户名
static String password = "123456";//密码
为了能够正确运行程序,各位读者需要把以上代码中的password值改为自己真实的数据库密码。
所有对数据库的操作都需要获得Connection对象,DBUtil类中定义了获得Connection对象的getConnection()方法,该方法的源代码如下:
public static Connection getConnection() throws SQLException {
con = DriverManager.getConnection(url, user, password);
return con;
}
以上的getConnection()方法中并没有加载驱动类的代码,其实加载驱动类的代码被写到了静态块中,这样就能在加载DBUtil类时自动完成驱动类的加载,这个静态块的代码如下:
static {
try {
Class.forName(driverName);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
当对完成对数据库的操作后都要释放资源,DBUtil类中定义了释放资源的close()方法,该方法的代码如下:
public static void close(ResultSet rs, Statement stm, Connection con) throws SQLException{
if (rs != null) {
rs.close();
}
if (stm != null) {
stm.close();
}
if (con != null) {
con.close();
}
}
24.2.2显示学生信息
当主窗体被打开后会自动显示学生信息,这些信息以分页的形式显示,默认情况下将显示第一页的学生信息。如果用户在条件文本框中输入查询条件并单击“查询”按钮,系统会显示满足条件的数据。显示学生信息由showInfo()方法实现,这个方法有一个int参数型,该参数指定显示的页数,也就是说如果设置参数值为1则显示第1页的数据,设置参数值为2则显示第2页的数据。showInfo()方法在执行过程中会判断用户是否为查询设置了条件,判断方法是:如果条件文本框中有非空字符,则认为这个非空字符串即为查询条件,否则认为没有查询条件。showInfo()方法在其内部会调用StudentDao类的query()方法查询出满足条件的数据,如果没有设置查询条件,则该方法会查询全部数据。当查询出数据后会调用setData()方法把这些数据显示到表格中。showInfo()方法的源代码如下:
private void showInfo(int page) {
String colName = "";
String keywords = txtKeywords.getText();
//如果有查询关键字则转换出相应列名称
if(keywords.trim().length()!=0) {
colName = getColName();
}
try {
ArrayList<Student> list = StudentDao.query(colName, keywords, page);
int num = StudentDao.getStudentNum(colName, keywords);
//计算总页数
if (num % 10 == 0) {
pageCount = num / 10;
}else {
pageCount = num / 10 + 1;
}
// 如果总页数为0,当前页也赋值为0
if (pageCount == 0) {
curPage = 0;
}
setData(list);// 把查询到的数据装入表格
lblPage.setText(curPage + "/" + pageCount);
} catch (Exception e) {
e.printStackTrace();
}
}
在MainFrame类中使用curPage属性记录当前页数,用pageCount属性记录某次查询所得到数据的总页数。由于showInfo()方法能够显示指定页数的数据,所以只需要为showInfo()方法传递参数curPage-1就能查询并显示上一页数据,而传递参数curPage+1就能查询并显示下一页数据,传递参数1就能显示首页数据,传递参数pageCount就能显示末页数据,窗体上的四个翻页按钮就是调用showInfo()方法并传递不同参数值实现翻页操作的。当然,每次翻页时都需要对页数进行合理性判断,例如,当前页数为1时,再单击“上页”按钮时应提示用户已经是第1页。
24.2.3新增学生信息
新增学生信息时,用户需要先单击“新增”按钮,这样会弹出信息详情对话框,在新增模式下这个对话框中用于填写信息的各文本框中都没有任何文本,如图24-2所示。
在这个对话框中,用户填写学生相关的各项信息,并单击“确定”按钮,此时会调用DetailDialog类的checkData()方法验证每一项信息的合理性,例如验证手机号是否为11位等。如果验证发现信息填写不合理则给出用户相应的提示并且方法返回null,反之如果全部信息全都填写正确,则把用户填写的各项信息存入一个Student类对象中。因此,程序可以通过checkData()方法的返回值是否为空判断出信息填写是否正确,如果全部信息都填写正确,就调用StudentDao类的insert()方法把这个学生的信息插入到数据库中。checkData()方法的源代码如下:
//检查数据的合理性,如果数据合理则返回组装好的Student对象,否则返回null
private Student checkData() {
String sid = txtSid.getText();
String name = txtName.getText();
String sex = "";
String classId = txtClassId.getText();
String phone = txtPhone.getText();
String info = txaInfo.getText();
if(sid.length()==0) {//如果学号为空
JOptionPane.showMessageDialog(DetailDialog.this, "学号不能为空!");
return null;
}
if(sid.length()>=10) {//如果学号长度超过10
JOptionPane.showMessageDialog(DetailDialog.this, "学号长度不能超过10!");
return null;
}
if(mode==ADD) {//如果是新增学生信息,则检查学号重复性
if(StudentDao.isStudentExists(sid.trim())) {
JOptionPane.showMessageDialog(DetailDialog.this, "学号出现重复,不能新增!");
return null;
}
}
if(name.length()==0) {//如果姓名为空
JOptionPane.showMessageDialog(DetailDialog.this, "姓名不能为空!");
return null;
}
if(name.length()>=10) {//如果姓名长度超过10
JOptionPane.showMessageDialog(DetailDialog.this, "姓名长度不能超过10!");
return null;
}
//如果没有选择性别
if(rbtMale.isSelected()==false && rbtFemale.isSelected()==false) {
JOptionPane.showMessageDialog(DetailDialog.this, "请选择性别!");
return null;
}else {//选择了性别的情况下把所选性别赋值给sex
if(rbtMale.isSelected()){
sex = rbtMale.getText();
}else{
sex = rbtFemale.getText();
}
}
if(classId.length()==0) {//如果班级为空
JOptionPane.showMessageDialog(DetailDialog.this, "班级不能为空!");
return null;
}
if(classId.length()>=10) {//如果班级长度超过10
JOptionPane.showMessageDialog(DetailDialog.this, "班级长度不能超过10!");
return null;
}
if(phone.length()!=11) {//如果手机号不是11位
JOptionPane.showMessageDialog(DetailDialog.this, "手机号必须是11位!");
return null;
}
if(info.length()>=50) {//如果备注信息长度超过50
JOptionPane.showMessageDialog(DetailDialog.this, "备注信息不能超过50个字!");
return null;
}
Student student = new Student();
//把用户填写的数据组装到Student对象中
student.setSid(sid);
student.setName(name);
student.setSex(sex);
student.setClassId(classId);
student.setPhone(phone);
student.setInfo(info);
return student;
}
需要提醒各位读者:修改学生信息操作时也需要对修改后的信息再次进行验证,这个验证也是由checkData()方法实现的,只是修改操作时不会验证当前学号是否与数据库总已有的学号重复。此外,当完成新增操作后,为了让用户能够在表格上看到他所新增的数据,还需要重新在主窗体上调用查询和显示数据的showInfo()方法。
24.2.4修改学生信息
修改学生信息时首先需要从表格中选定待修改的学生,然后单击“修改”按钮,此时会弹出信息详情对话框,与新增模式不同,修改模式下的信息详情对话框会自动把该学生的信息显示出来,让用户在原信息的基础完成修改,用户在这个对话框中可以修改除学号以外的任何信息,如图24-4所示。
把选定的学生信息显示到各个文本框需要先按照学生的学号查询到该学生的信息,然后把该学生的各项信息填入对应的文本框中,查询选定学生信息以及把信息写入文本框的代码位于DetailDialog类的init()方法中,这些代码如下:
student = StudentDao.queryBySid(sid);
this.txtSid.setText(student.getSid());//反写学号
this.txtSid.setEditable(false);//学号只读
this.txtName.setText(student.getName());//反写姓名
this.txtClassId.setText(student.getClassId());//反写班级
this.txtPhone.setText(student.getPhone());//反写手机号
this.txaInfo.setText(student.getInfo());//反写备注
if("男".equals(student.getSex())) {//反选性别
this.rbtMale.setSelected(true);
}else {
this.rbtFemale.setSelected(true);
}
修改后的各项信息仍然要通过checkData()方法进行验证,只有全部信息都通过验证才能进行修改,修改数据库中的数据要调用StudentDao类的update()方法完成,而窗体表格中所显示的信息也要进行相应的修改,这个修改操作可以通过以下代码实现:
//把更新后对象的各项信息刷新到表格的各单元格中
table.setValueAt(student.getName(), row, 1);
table.setValueAt(student.getClassId(), row, 2);
table.setValueAt(student.getSex(), row, 3);
table.setValueAt(student.getPhone(), row, 4);
之所以要在表格上直接修改数据而不是重新查询一次数据库并显示到表格上,是因为这样的操作避免了数据库的查询和大量的数据加载,能够大大的提高程序的运行速度。
24.2.5查看学生信息详情
当用户从信息列表中选定一条信息后,单击“详情”按钮即可查看学生信息详情。查看学生信息详情与修改学生信息都会把学生的各项信息自动显示到对话框中,其实现原理是完全相同的,但查看信息详情模式下所有文本框都处于只读状态,设置文本框为只读状态的代码如下:
//如果是详情模式则设置组件为不可编辑状态
if(mode==DETAIL) {
this.txtName.setEditable(false);
this.txtClassId.setEditable(false);
this.txtPhone.setEditable(false);
this.txaInfo.setEnabled(false);
this.rbtMale.setEnabled(false);
this.rbtFemale.setEnabled(false);
}
查看学生信息详情与修改学生信息使用同一个对话框进行操作,但在这种模式下只能查看数据而不能修改数据,并且单击“确定”或“取消”按钮后都只会直接退出对话框,不会有任何其他操作。
24.2.6删除学生信息
删除学生信息时也需先从信息列表中选定一条信息,然后单击“删除”按钮,此时系统会弹出对话框让用户确认是否要真的删除学生信息,如果选择“确定”则删除该学生的信息。删除数据库中对应的数据需要用deleteBySid()方法实现,而删除列表中的信息需要分三种情况采用不同的实现方法。
第一种情况:总共只有一条数据,则直接从列表中删除这条数据。第二种情况:本页是最后一页且本页只有一条数据,在这种情况下删除了这条数据后本页再无其他数据,所以在删除这条数据后要查询上一页数据并把它们显示到数据列表中。第三种情况:本页中有2条或以上的数据,在这种情况下删除数据后要重新查询本页数据并显示,这种情况下之所以要重新查询而不是简单的把所选中的数据从列表中删掉,是因为有可能要在删除数据后需要用下一页的第一条数据填充至本页,而下页中的数据只能查询获得。删除数据后处理数据列表的代码如下:
//计算删除一条数据后总共剩余多少条数据
int num = StudentDao.getStudentNum(colName, keywords);
if(num==0) {//如果删掉之后再无数据
data.removeRow(row);//
curPage = 0;
pageCount = 0;
lblPage.setText(curPage+"/"+pageCount);
}else if(data.getRowCount()==1) {//本页仅一条数据
curPage--;//当前页减1(即回到上一页)
showInfo(curPage);//查询上页数据
}else {
showInfo(curPage);//查询本页数据
}
本文字版教程还配有更详细的视频讲解,小伙伴们可以点击这里观看。