班级通讯录管理系统(java大作业完美版) 下载本文

1

一、 问题及功能分析

需求分析

功能需求:

1、 提供身份验证:能否使用该系统。 2、 提供用户注册及修改密码功能。

3、提供对同学通讯信息的增加、删除、修改和查询功能。

4、查询功能要求:能实现根据学号、姓名的精确查询,也能对地区的模糊查询,比如:查询“广州市天河区”,能列出所有家在广州市天河区的同学信息。

性能需求:

1、 操作界面美观、友好。

2、 通讯录采用MySQL数据库再用JDBC连接。

系统功能结构

经过需求分析,此班级通讯录主要包括用户的注册登录模块和对联系人的信息管理模块,系统结构如图

添加联系人 联系人信息管理 班级通讯录管理系统 注册登录 修改联系人资料 查询联系人信息 联系人照片管理 显示联系人信息 系统结构图

修改登录密码 注册新用户 用户登录 目录结构

2

该软件主要的实体有用户、联系人和照片,下面介绍各实体的E-R图,通过E-R图来了解实体属性,这里主要介绍联系人和联系人照片的E-R图。

数据库表的设计

本软件共建了三张表:用户表、联系人表和照片表。

联系人表 字段名称 数据类型 字段大小 是否主键 说明 3

Pid pname pgender pbirthday pnumber pQQ pemail padress pphoto Uid 文本 文本 文本 文本 文本 文本 文本 文本 OLE 对象 文本 20 20 4 20 12 20 20 50 N/A 20 是 否 否 否 否 否 否 否 否 否 联系人编号 联系人姓名 性别 生日 联系电话 QQ号码 电子邮件 联系地址 照片 所属用户 照片表 字段名称 pid photoname photo 数据类型 文本 文本 OLE 对象 字段大小 2 50 N/A 是否主键 否 是 否 说明 所属联系人 照片名称 照片数据 用户表

字段名称 uid pwd 数据类型 文本 文本 字段大小 20 20

是否主键 是 否 说明 用户登录名 登录密码 二、 概要设计

1、 构建开发环境

开发此通讯录所用到的软件环境 ? JDK 1.7版本 ? MySQL 5.5

? Navicat Premium 数据库可视化工具 ? Myeclipse开发工具 2、 图形用户界面构成

4

? 登录模块

用户名、密码两个JLabel ,登录、注册、修改密码按钮JButton ,输入用户名、密码的文本框。如图

? 联系人信息管理模块

界面上部分是实现查询功能的组件,中间部分是信息显示组件,下面部分是查询返回的JTable列表。如图

5

三、 详细设计

1、 登录界面的搭建 login.java

运用了PS设计一些icon以及页面布局方法,实现了登录界面的美化。(详细代码请看工程文件夹下文件login.java) 3、 登录窗口功能的实现

login.java、DButil.java

提供了登录校验方法,包括账号密码合法性、修改密码、注册等。(详细代码请看工程文件夹下文件login.java、 DButil.java) 4、 主窗体的搭建及功能 MainFrame.java

窗体界面布局,各个事件的监听以及实现。如:查询操作。(详细代码请看工程文件夹下文件MainFrame.java)

5、 登录窗体及联系人信息管理窗体所用到的数据库操作方法 DButil.java

定义各种数据库操作方法。如:登录验证、注册、查询、插入等。(详细代码请看工程文件夹下文件DButil.java)

2、 登录界面的搭建

6

3、 package Frame;

4、 import java.awt.*;

5、 import java.awt.event.ActionEvent; 6、 import java.awt.event.ActionListener; 7、 import java.sql.*; 8、 import javax.swing.*; 9、 import db.DButil;

10、 public class login extends JFrame implements

ActionListener{ 11、 private JPanel jp=new JPanel(); 12、 //创建标签数组 13、 private JLabel[] jlArray={new JLabel(\用户名\), new

JLabel(\密 码\),new JLabel(\)}; 14、 15、 private JButton jb1; 16、 private JButton jb2; 17、 private JButton jb3; 18、 private JTextField jtf=new JTextField(); 19、 private JPasswordField jpf=new JPasswordField(); 20、 21、 //布局构造实现方法 22、 23、 public login(){ 24、 Icon icon1=new ImageIcon(\); 25、 Icon icon2=new ImageIcon(\); 26、 Icon icon3=new ImageIcon(\); 27、 28、 JPanel jp=new JPanel(){ 29、 protected void paintComponent(Graphics g) { 30、 ImageIcon icon = new

ImageIcon(\); 31、 Image img = icon.getImage(); 32、 g.drawImage(img, 0, 0,

icon.getIconWidth(), icon.getIconHeight(), icon.getImageObserver()); 33、 }}; 34、 jp.setLayout(null); 35、 jb1=new JButton(icon1); 36、 jb2=new JButton(icon3); 37、 jb3=new JButton(icon2); 38、 jlArray[0].setBounds(70,120,90,32); 39、 jb1.setBounds(365,110,130,60); 40、 jb2.setBounds(365,170,130,60); 41、 jlArray[1].setBounds(70,170,90,32); 42、 //将标签与按钮添加到JPanel容器中 43、 jp.add(jlArray[0]); 44、 jp.add(jlArray[1]); 45、 jp.add(jb1); 46、 jp.add(jb2); 47、 jb1.addActionListener(this); 48、 jb2.addActionListener(this);//为按钮注册动作事

件监听器 49、 //添加修改密码的按钮

7

50、 jb3.setBounds(365,230,130,60); 51、 jp.add(jb3); 52、 jp.add(jtf); 53、 jtf.setBounds(140,120,180,30);//设置文本框位置 54、 jp.add(jpf); 55、 jpf.setBounds(140,170,180,30);//设置密码框位置 56、 jpf.setEchoChar('*'); //密码显示字符形式 57、 jpf.addActionListener(this); //为密码框注册

动作事件监听器 58、 this.setVisible(true);//设置窗体的可见性 59、 jpf.addActionListener(this); //为密码框注册

动作事件监听器 60、 //设置用于显示登陆状态的标签大小位置,并将其添加进

JPanel容器 61、 jlArray[2].setBounds(70,220,300,30); 62、 jp.add(jlArray[2]); 63、 this.setTitle(\登陆\);//设置窗体标题 64、 this.setBounds(450,200,500,318);//设置窗体的大

小 65、 this.setResizable(false);//设置窗体不让用户调整

大小 66、

this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 67、 this.setVisible(true);//设置窗体的可见性 68、 this.add(jp);//将窗体添加到面板中 69、 jp.setBackground(Color.blue);

70、

}

71、 public static void main(String[] args) { 72、 new login();//创建登陆窗体 }

73、 }

6、 登录窗口功能的实现

public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub //得到用户名与密码 String user=jtf.getText().trim(); String pwd=String.valueOf(jpf.getPassword());//返回密码的字符串表示方式 String sql=\; if(e.getSource()==jtf){//事件源为文本框,切换焦点到密码框 jpf.requestFocus(); } else if(e.getSource()==jb1||e.getSource()==jpf){ //判断用户名和密码是否匹配 查询数据库 if(DButil.check(user, pwd)){ //登陆成功 MainFrame mf=new MainFrame(jtf.getText());//主窗体 this.dispose(); } else{ //登陆失败 jlArray[2].setText(\对不起,非法的用户名和密码\); this.clear(); } }

8

else if(e.getSource()==jb2) {//事件源为注册按钮 if(user.equals(\)||pwd.equals(\)) {//如果注册的用户名为空或者密码为空 jlArray[2].setText(\用户名和密码都不得为空!!!\); this.clear();//清空输入文本框 } else { sql=\+user+\; if(DButil.isExist(sql)) {//用户名已经存在 jlArray[2].setText(\对不起,用户名已存在!!!\); this.clear();//清空输入文本框 } else { sql=\values('\+user+\+pwd+\; if(DButil.update(sql)>0) {//注册成功 jlArray[2].setText(\恭喜您!!!注册成功,请登陆\); } } } } else if(e.getSource()==jb3)//修改密码的监听 { //判断是否已经输入用户名和密码 if(user.equals(\)||pwd.equals(\)) { jlArray[2].setText(\修改密码先输入正确的用户名和密码!!!\); this.clear();//清空输入文本框 } //判断是否输入了正确的用户名和密码 else if(DButil.check(user,pwd)) { //正确的用户名和密码 String password=JOptionPane.showInputDialog(this,\修改密码:\,\请输入新密码\, JOptionPane.PLAIN_MESSAGE); //得到新的密码为空 if(password==null||password.equals(\)) { JOptionPane.showMessageDialog(this,\密码不得为空!!!\,\错误\, JOptionPane.WARNING_MESSAGE); } else {//密码不为空 sql=\+password+%uid='\+user+\;//更新密码的SQL if(DButil.update(sql)>0) {//密码修改成功

9

this.clear();//清空输入文本框 jlArray[2].setText(\恭喜您!!!密码修改成功,请用新密码登陆\); } } } else { JOptionPane.showMessageDialog(this,\用户名或者密码错误!!!\,\错误\, JOptionPane.WARNING_MESSAGE); this.clear();//清空输入文本框 } }

}

7、 主窗体的搭建及功能 package Frame;

import javax.swing.*;

import javax.swing.table.DefaultTableModel; import db.DButil; import java.awt.*;

import java.awt.event.*; import java.sql.*; import java.io.*; import java.util.*; public class MainFrame extends JFrame implements ActionListener,ItemListener { private String uname=null;//当前用户的名字 private boolean isInsert=false;//是否为添加默认为否 private JPanel topjp=new JPanel();//界面上半部分的JPanel容器 private JButton jba=new JButton(\模糊查询\ private JButton jbs=new JButton(\查找\ private JTextField jtfs=new JTextField();//按给出信息查找联系人信息 private JRadioButton jrbxm=new JRadioButton(\按姓名查找\ private JRadioButton jrbbh=new JRadioButton(\按学号查找\ private ButtonGroup bg=new ButtonGroup();//单选按钮组 private JPanel jpbr=new JPanel();//单选按钮面板 private JPanel jpyInfo=new JPanel();//右侧显示个人信息的面板 private JTextArea jta=new JTextArea(); // 模糊查询得到的信息文本区 private JLabel[] jlInfo={new JLabel(\学号:\姓名:\ new JLabel(\性别:\出生日期:\ new JLabel(\电话号码:\ new JLabel(\地址:\ new JLabel(\添加相片\

10

private JButton[] jbInfo={new JButton(\编辑\保存\ new JButton(\浏览\new JButton(\上传\ private JLabel jlPhoto=new JLabel();//显示图像的JLabel控件 private JTextField[] jtfInfo=new JTextField[10]; private JTextField jtfPhoto=new JTextField();//添加照片到相册的路径 private JFileChooser jfcPic=new JFileChooser();//上传图像的文件选择器 private DefaultTableModel tableModel; private JTable table; //性别部分 private JRadioButton jrbMale=new JRadioButton(\男\ private JRadioButton jrbFemale=new JRadioButton(\女\ private ButtonGroup bgGender=new ButtonGroup(); private JPanel jpGender=new JPanel();//单选按钮面板 private JLabel jlDetail=new JLabel();//右侧显示一幅图片的标签 private JSplitPane jspOuter=//上下分割的JSplitPane new JSplitPane(JSplitPane.VERTICAL_SPLIT,true); //系统托盘部分 private PopupMenu popup=new PopupMenu(); private SystemTray tray;//定义SystemTray成员变量 private TrayIcon trayIcon;//定义TrayIcon成员变量 private MenuItem exit=new MenuItem(\退出程序\定义菜单 public void initJps() {//界面上半部分的初始化 topjp.setLayout(null);//设置topjp布局管理器为null //设置按钮大小并添加到JPanel面板里 jba.setBounds(5,10,120,26); jba.addActionListener(this);//为模糊查询按钮注册事件监听器 topjp.add(jba); jbs.setBounds(130,10,80,26); jbs.addActionListener(this);//为查找按钮注册事件监听器 topjp.add(jbs);//添加按钮到topjp面板里 //设置jtfs文本框大小并添加到jps面板里 jtfs.setBounds(215,10,120,26); jtfs.addActionListener(this);//为文本框注册事件监听器 topjp.add(jtfs);

11

//设置单选按钮大小和位置并添加到jpbr面板里同时添加到bg单选按钮组里 jrbxm.setBounds(5,3,50,26); jrbxm.addItemListener(this);//为单选按钮注册ItemEvent事件监听器 bg.add(jrbxm); jpbr.add(jrbxm); jrbbh.setBounds(60,3,50,26); jrbbh.addItemListener(this); bg.add(jrbbh); jpbr.add(jrbbh); jpbr.setBounds(360,10,200,26); topjp.add(jpbr); } public void initInfo() {//初始化信息界面 jpyInfo.setLayout(null);//设置布局管理器为空 jpyInfo.setBounds(50,50,380,360);//设置信息面板的大小和位置 jlPhoto.setBounds(220,10,150,170);//设置联系人图像JLabel的大小和位置 jlPhoto.setBorder(BorderFactory.createLineBorder(Color.BLACK));//将JLbel的边框线显现出来 jpyInfo.add(jlPhoto);//将显示联系人照片的JLabel添加到信息面板 tableModel=new DefaultTableModel(); Vector vector1 = new Vector(); DButil db = new DButil(); vector1.add(\学号\ vector1.add(\姓名\ vector1.add(\性别\ vector1.add(\出生日期\ vector1.add(\电话号码\ vector1.add(\ vector1.add(\ vector1.add(\地址\ vector1.add(\照片路径\

tableModel.setDataVector(null, vector1); System.out.print(123);

table=new JTable(tableModel);

//table.addMouseListener((MouseListener) this); table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);

12

JScrollPane js=new JScrollPane(table); //添加相片部分的控件 jtfPhoto.setBounds(80,250,200,26);//设置得到照片路径的文本框的大小和位置 jpyInfo.add(jtfPhoto);//将得到照片路径的文本框添加到信息面板 jbInfo[2].setBounds(285,250,80,26); jbInfo[2].addActionListener(this);//为添加照片的浏览按钮注册事件监听器 jpyInfo.add(jbInfo[2]); //上传按钮 jbInfo[3].setBounds(380,250,80,26); jbInfo[3].addActionListener(this);//为添加照片的浏览按钮注册事件监听器 jpyInfo.add(jbInfo[3]); for(int i=0;i<9;i++)//添加JLabel,并设置大小和位置 { jlInfo[i].setBounds(20,10+i*30,60,26); jpyInfo.add(jlInfo[i]); } for(int i=0;i<10;i++) {//初始化一些文本框 jtfInfo[i]=new JTextField(); } //学号 jtfInfo[0].setBounds(80,10,135,26); jpyInfo.add(jtfInfo[0]); //姓名 jtfInfo[1].setBounds(80,40,135,26); jpyInfo.add(jtfInfo[1]); //出生日期 jtfInfo[3].setBounds(80,100,135,26); jpyInfo.add(jtfInfo[3]); //电话号码 jtfInfo[4].setBounds(80,130,135,26); jpyInfo.add(jtfInfo[4]); //QQ jtfInfo[5].setBounds(80,160,135,26); jpyInfo.add(jtfInfo[5]); //Email jtfInfo[6].setBounds(80,190,135,26); jpyInfo.add(jtfInfo[6]); //地址文本框的添加 jtfInfo[7].setBounds(80,220,285,26); jpyInfo.add(jtfInfo[7]);

13

//模糊查询信息文本区的添加 js.setBounds(0,350,600,100); jpyInfo.add(js); //编辑、保存按钮 jbInfo[0].setBounds(160,300,80,26); jbInfo[0].addActionListener(this); jpyInfo.add(jbInfo[0]); jbInfo[1].setBounds(260,300,80,26); jbInfo[1].addActionListener(this); jpyInfo.add(jbInfo[1]); //性别部分 jrbMale.setBounds(5,3,50,26); jrbMale.addItemListener(this); //为单选按钮注册ItemEvent事件监听器 bgGender.add(jrbMale); jpGender.add(jrbMale); jrbFemale.setBounds(60,3,50,26); jrbFemale.addItemListener(this); //为单选按钮注册ItemEvent事件监听器 bgGender.add(jrbFemale); jpGender.add(jrbFemale); jpGender.setBounds(60,70,125,26); jpyInfo.add(jpGender); } public void clearInfo()//清空信息面板 { for(int i=0;i<10;i++) { jtfInfo[i].setText(\清空文本框 } jlPhoto.setIcon(null);//清空图像 } public void setjtaArea(String information){ if(information.isEmpty()){ JOptionPane.showMessageDialog(this,\所查用户不存在!!!\错误\ JOptionPane.WARNING_MESSAGE); } else { jta.setText(information); } }

14

public void setInfo(Vector pInfo)//将信息向量设置到信息面板中 {//将信息向量按规则填到信息面板里 this.clearInfo(); if(pInfo.size()==0) { JOptionPane.showMessageDialog(this,\所查用户不存在!!!\错误\ JOptionPane.WARNING_MESSAGE); } else { for(int i=0;i<2;i++) {//显示联系人编号和姓名 jtfInfo[i].setText(pInfo.get(i)); } if(pInfo.get(2).equals(\男\ {//显示性别 jrbMale.setSelected(true); } else {//显示性别 jrbFemale.setSelected(true); } for(int i=3;i<9;i++) {//显示出生日期、电话号码和QQ jtfInfo[i].setText(pInfo.get(i)); } } } public Vector getInfo()//从信息面板得到用户输入的信息 { Vector pInfo=new Vector(); pInfo.add(jtfInfo[0].getText().trim());//添加pid pInfo.add(jtfInfo[1].getText().trim());//添加pname String gender=jrbMale.isSelected()?\男\女\ pInfo.add(gender);//添加性别 pInfo.add(jtfInfo[3].getText().trim());//出生日期 pInfo.add(jtfInfo[4].getText().trim());//电话号码 pInfo.add(jtfInfo[5].getText().trim());//QQ pInfo.add(jtfInfo[6].getText().trim());//Email

15

pInfo.add(jtfInfo[7].getText().trim());//地址 String photoPath=jtfPhoto.getText().trim();//得到照片路径 pInfo.add(photoPath);//照片路径 return pInfo; } public void monitorSaveButton() //监听保存按钮的方法 { String sql=\ String pid=jtfInfo[0].getText().trim();//得到联系人的编号 String pname=jtfInfo[1].getText().trim();//得到联系人的姓名 String gender=jrbMale.isSelected()?\男\女\ String s1=jtfInfo[3].getText().trim(); String s2=jtfInfo[4].getText().trim(); String s3=jtfInfo[5].getText().trim(); String s4=jtfInfo[6].getText().trim(); String s5=jtfInfo[7].getText().trim(); String s6=jtfPhoto.getText().trim(); String sqla=\判断此编号是否存在的SQL String sqlb=\* from contacts where pname='\判断此姓名是否存在的SQL boolean isIdExist=DButil.isExist(sqla);//得到编号是否存在 boolean isNameExist=DButil.isExist(sqlb);//得到姓名是否存在 if(!(pid.equals(\ { if(isIdExist||isNameExist){ JOptionPane.showMessageDialog(this,\联系人已存在\ \ , 添加联系人失败\错误\ } else { sql=\into contacts values (?,?,?,?,?,?,?,?,?,?)\ String[]

paras={pid,pname,gender,s1,s2,s3,s4,s5,s6,null}; if(DButil.update(sql,paras)>0){ JOptionPane.showMessageDialog(this,\联系人保存成功\提示\ JOptionPane.INFORMATION_MESSAGE); } } }

16

} public void setEditable(boolean Editable)//设置信息窗口是否可编辑 { jrbFemale.setEnabled(Editable);//设置性别是否可编辑 jrbMale.setEnabled(Editable);//设置性别是否可编辑 for(int i=0;i<8;i++) { jtfInfo[i].setEditable(Editable);//设置文本框是否可编辑 } } public void monitorSearchButton()//监听查找按钮的方法 { String name=jtfs.getText().trim(); String sql=\声明查找字符串 if(name.equals(\ { JOptionPane.showMessageDialog(this,\查找条件不能为空!!!\ \错误\ JOptionPane.WARNING_MESSAGE); } else { if(jrbxm.isSelected()==true) {//按姓名查找 sql=\

pid,pname,pgender,pbirthday,pnumber,pQQ,pemail,padress,pphoto from contacts where pname='\ this.setInfo(DButil.getPerInfo(sql));//设置信息面板为该联系人的信息 } else {//按编号查找 sql=\

pid,pname,pgender,pbirthday,pnumber,pQQ,pemail,padress,pphoto from contacts where pid='\ this.setInfo(DButil.getPerInfo(sql));//设置信息面板为该联系人的信息

17

} } this.setEditable(false);//设置面板不可编辑 } public void monitorRandomSearchButton(String information){ //监听模糊查询按钮 String adress=jba.getText().trim(); String sql=\声明查找字符串 if(adress.equals(\ { JOptionPane.showMessageDialog(this,\查找条件不能为空!!!\ \错误\ JOptionPane.WARNING_MESSAGE); } else{ sql=\

pid,pname,pgender,pbirthday,pnumber,pQQ,pemail,padress,pphoto from contacts where padress like '%天河区%'\ } } public MainFrame(String uname) { //主窗体构造器 this.uname=uname;//设置用户名 this.initJps();//界面上半部分的搭建 this.initInfo(); jspOuter.setDividerLocation(46);//设置分割窗体JSplitPane的位置 jspOuter.setTopComponent(topjp);//设置窗体上半部分的控件 jspOuter.setBottomComponent(jpyInfo);//设置下半部分的控件 //设置窗体关闭按钮执行的动作 this.add(jspOuter); this.addWindowListener( new WindowAdapter() { @SuppressWarnings(\ public void WindowClosing(WindowEvent e) { //将窗体隐藏 MainFrame.this.hide(); } }

18

); //设置主窗体的图标、标题、大小以及可见性 this.setResizable(false);//设置窗体不让调整大小 this.setTitle(uname+\的通讯录\ this.setBounds(420,80,618,550); this.setVisible(true); }

public void actionPerformed(ActionEvent e) { if(e.getSource()==jbInfo[1]) {//保存按钮的监听 this.monitorSaveButton(); }

else if(e.getSource()==jba) {//模糊查询按钮的监听

DButil db = new DButil();

Vector vector1 = new Vector(); vector1.add(\学号\ vector1.add(\姓名\ vector1.add(\性别\

vector1.add(\出生日期\ vector1.add(\电话号码\ vector1.add(\ vector1.add(\ vector1.add(\地址\

vector1.add(\照片路径\

String ad = jtfs.getText().trim();

tableModel.setDataVector(db.getData(ad),vector1); }

else if(e.getSource()==jbInfo[2]) {//打开图像文件路径 jfcPic.showOpenDialog(this); if(jfcPic.getSelectedFile()!=null) { jtfPhoto.setText(\ } }

else if(e.getSource()==jbInfo[0]) {//编辑按钮的监听 this.setEditable(true);//设置信息面板可编辑 }

else if(e.getSource()==jbs||e.getSource()==jtfs)

19

{//查找,按按钮或者在文本框里敲回车 this.monitorSearchButton(); } } public void itemStateChanged(ItemEvent e) { } public static void main(String[] args){ } }

8、 登录窗体及联系人信息管理窗体所用到的数据库操作方法 package db;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileNotFoundException; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet;

import java.sql.ResultSetMetaData; import java.sql.Statement; import java.util.Vector; public class DButil { private static String jdbcName=\声明驱动类字符串 //声明数据库连接字符串 private static String dbUrl=\ private static String dbUserName=\ private static String dbPassword=\ private static Connection con=null;//声明数据库连接对象引用 private static Statement stat=null;//声明语句对象引用 private static PreparedStatement pstmt=null; private static ResultSet rs=null;//声明结果集对象引用 private static PreparedStatement psInsert=null;//声明预编译语句对象引用 public static Connection getConnection()//得到数据库连接的方法 { System.out.println(\连接中..\ try {

20

Class.forName(jdbcName);//加载驱动类 con=DriverManager.getConnection(dbUrl,dbUserName,dbPassword);//得到连接 System.out.println(\成功连接\ } catch(Exception e){e.printStackTrace();} return con;//返回连接 } public static boolean check(String user,String pwd)//登陆验证 { boolean flag=false; try { con=DButil.getConnection();//得到数据库连接 stat=con.createStatement();//创建语句对象 rs=stat.executeQuery(\pwd from user where uid='\ rs.next(); String spwd=rs.getString(1);//得到密码 if(spwd.equals(pwd)) { flag=true;//密码匹配,登陆成功 } } catch(Exception e) { flag=false;//有任何异常发生,登陆失败 } finally{DButil.closeCon();}//关闭数据库连接 return flag; } //某条记录是否存在 public static boolean isExist(String sql) { boolean flag=false;//设置返回值 try { con=DButil.getConnection();//得到数据库连接 stat=con.createStatement();//创建语句对象 rs=stat.executeQuery(sql);//执行查询 if(rs.next()) { flag=true;//存在,设置返回值为true

21

} } catch(Exception e) { e.printStackTrace(); flag=false;//发生任何异常,置返回结果为false } finally{DButil.closeCon();}//关闭数据库连接 return flag;//返回结果 } public static int update(String sql,String[] paras)//更新数据库 { int count=0;//声明返回值 try { con=DButil.getConnection(); pstmt=con.prepareStatement(sql); for(int i=0; i

22

} finally{DButil.closeCon();}//关闭数据库连接 return count;//返回结果 } //====================添加联系人================================= public static String insertPerson(String uid,Vector pInfo) { String isPathNull=\传过来的图像是不是合法,默认不为空 try{ con=getConnection();//得到数据库连接 if(pInfo.get(8).equals(\ {//照片路径为空,则不插入图像 psInsert=con.prepareStatement(\into contacts(pid,pname,pgender,pbirthday,pnumber,\ \ \ } else {//照片路径不为空,则插入图像 psInsert=con.prepareStatement(\into contacts(pid,pname,pgender,pbirthday,pnumber,\ \ \ File f=new File(pInfo.get(8));//获取选取的图片文件 byte[] b=new byte[(int)f.length()];//创建存储图片数据的数组 FileInputStream fin=new FileInputStream(f); fin.read(b);fin.close();//读取文件存于byte数组中并关闭输入流 psInsert.setBytes(11,b);//设置pphoto参数的数据 } for(int i=0;i<8;i++) {//设置公共信息 psInsert.setString(i+1,pInfo.get(i)); } psInsert.setString(10,uid);//所属用户 psInsert.execute();psInsert.close();//执行更新并关闭语句 } catch(FileNotFoundException fnfe){isPathNull=\图片

23

路径不对 catch(Exception e){e.printStackTrace();} finally{DButil.closeCon();}//关闭数据库连接 return isPathNull; } public static String updatePerson(String uid,Vector pInfo){ String isPathNull=\传过来的path是不是合法 try{ con=getConnection(); if(pInfo.get(9).equals(\ {//更新时候,如果照片路径为空,则不更新图像 psInsert=con.prepareStatement(\contacts set pname=?,pgender=?,birthday=?,pnumber=?,\ \where pid='\ } else {//如果照片路径不为空,则更新图像 psInsert=con.prepareStatement(\contacts set pname=?,pgender=?,page=?,pnumber=?,\ \where pid='\ File f=new File(pInfo.get(9));//获取选取的图片文件 byte[] b=new byte[(int)f.length()];//创建存储图片数据的数组 FileInputStream fin=new FileInputStream(f); fin.read(b);fin.close();//读取文件存于byte数组中并关闭输入流 psInsert.setBytes(10,b); } for(int i=1;i<8;i++){//设置公共的信息部分 psInsert.setString(i,pInfo.get(i)); } psInsert.setString(9,uid);//所属用户 psInsert.execute();psInsert.close();//执行更新并关闭语句 } catch(FileNotFoundException fnfe){isPathNull=\路径不合法 catch(Exception e){e.printStackTrace();} finally{DButil.closeCon();}//关闭连接 return isPathNull; }

24

public Vector getData(String ad){ Vector vector=new Vector(); try { //陈述对象 con=getConnection();//得到数据库连接 stat=con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);//创建语句对象 rs=stat.executeQuery(\LIKE '%\ ResultSetMetaData rm=rs.getMetaData(); //循环打印出数据库表中数据 int n=rm.getColumnCount(); while(rs.next()){ Vector ve=new Vector(); for(int i=1;i

25

if(con!=null){ try { con.close();//关闭连接 } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } return vector; } public static Vector getPerInfo(String sql)//得到联系人信息 { Vector pInfo=new Vector(); try { con=getConnection();//得到数据库连接 stat=con.createStatement();//创建语句对象 rs=stat.executeQuery(sql);//执行查询 while(rs.next()) { for(int i=1;i<10;i++) { System.out.println(rs.getString(i)); pInfo.add(rs.getString(i));//将联系人信息添加到返回向量 } } } catch(Exception e) { e.printStackTrace(); } finally{DButil.closeCon();}//关闭数据库连接 return pInfo;//返回信息集合 } public static void closeCon()//关闭数据库连接的方法 {

26

try { if(rs!=null){rs.close(); rs=null;}//如果结果集不为空关闭结果集并赋值null if(stat!=null){stat.close(); stat=null;}//如果语句对象不为空关闭语句对象并赋值null if(con!=null){con.close(); con=null;}//如果连接不为空关闭连接并赋值null } catch(Exception e){e.printStackTrace();} } public static void main(String[] args){ DButil DB=new DButil(); System.out.println(DB.getConnection()); } }

四、 调试分析

1、 登录窗体功能调试

? 注册

在文本框输入用户名、密码,点击注册,提示注册成功,用户名与编号存入数据库user表。

? 登录

27

输入正确的用户名与密码,点击登录进入主窗体 ? 修改密码

输入已注册过的正确的用户名与密码,点击修改密码,在弹出得窗口输入新密码,确定后新密码会存入数据库替换原密码,提示修改成功。

2、 联系人信息管理窗体功能调试 ? 添加联系人

在各个资料输入文本框输入资料,点击保存按钮,联系人资料存进数据库contacts表中 ,若学号或姓名以存在,则保存失败。

28

? 查询功能

精确查询:

按姓名查询,查询后信息框不允许编辑,点击编辑可解锁编辑,并修改信息。

按学号查询:

29

? 模糊查询功能

在查询框输入关键字,点击模糊查询按钮,查询数据库存在此关键字的所以记录并以JTabel的形式打印在主窗体下方。

30

两个模块设计是遇到的问题:

1、 所遇到最多的问题就是与数据库之间参数的传递问题,如在模糊查询功能的时候,想把结果集生成一个列表,要用JTabel,然后就在将结果集返回到主窗体。

解决办法:百度,参考了网上的一个小例子。

2、 登录模块,页面美化问题,后来觉得实在是很难看,用户体验不好。 解决办法:用PS作了几张图,使用背景、图片设置以及组件定位布局。

五、 课设总结

1、 课程设计过程的收获

1) 最大的收获就是在开发此系统的时候,复习了Java SE 的大部分内容,包

括Swing,异常处理、IO等等。而且还运用到了刚学到的sqlserver数据库设计知识,还熟悉了mysql的使用.

2) 虽然此系统使用了数据库储存数据,但是数据结构的应用也不少。如

Arrays数组类的应用。java集合框架中的列表:动态数组存储方式Vector 等。

3) 课题设计过程中,分为逻辑设计和详细设计两个步骤实现.逻辑设计指的是,

对问题描述中涉及的操作对象定义相应的数据类型,并按照以数据为中心的原则划分模块,定义主程序模块和各抽象数据类型;详细设计则为定义相应

31

的方法并写出各函数的伪码算法.作为逻辑设计的结果,应写出每个抽象数据类型的定义。

4) 回顾起此课程设计,至今我仍感慨颇多,从理论到实践,在这段日子里,

可以说得是苦多于甜,但是可以学到很多很多的东西,同时不仅可以巩固了以前所学过的知识,而且学到了很多在书本上所没有学到过的知识。通过这次课程设计使我懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能真正为社会服务,从而提高自己的实际动手能力和独立思考的能力。在设计的过程中遇到问题,可以说得是困难重重,但可喜的是最终都得到了解决。

2、 遇到的问题及思考

1、 数据库之间参数的传递问题,这个问题开始弄得我心烦意乱,后来

静心分析了login、MainFrame、DButil这三个文件的关系后,理清了逻辑关系,问题慢慢得到了解决。

2、 安装及设置mysql时没设置好编码问题,导致保存联系人信息到数

据库时出现乱码问题,后来百度后修改了设置。

3、 未完全熟悉Myeclipse开发工具的使用,部分功能不会使用。 4、 发现断点调试很有用

5、 弹出对话框的使用:本软件中填写用户信息时,需要对这些信息进

行合法性验证,当用户输入不合法时,就需要用弹出对话框进行提示。在开发过程中,适当的使用弹出对话框,可以大大简化开发过程,减少许多不必要的操作

6、思考了数据库设计方面的知识,查阅了相关资料,发现数据库结构复杂的时候,表的设计是非常重要的,因为数据库系统设计的好坏将直接决定数据库系统的性能。