JAVA个人通讯录的实现

这个通讯录系统是有我和另一位同学共同实现,由于我源码丢失,因此转载该同学的文章。

2015-2016学年第1学期

《Java言程序设计(英)》课程大作业报告

 

课题名称:    《个人通讯录》            

小组成员人数(单选)□1人      ■2人      □3人

1. 软件系统分析

本软件是一个简化的联系人信息管理软件,通过注册本软件使用存储联系人信息的功能。

(1)通讯录功能模块

要实现的功能分别为用户管理、用户登录、添加联系人、修改联系人、删除联系人、查找联系人。如图:

 

(2)数据库内容

建立两个数据表分别为,用户表和联系人表

1、用户表中包含用户的ID、姓名、密码三变量,用于储存用户登录和注册信息。

2、联系人表包含编号、姓名、性别、年龄、电话、Email、邮编、传真、地址、分组、照片和备注等信息。

用户表和联系人表的关系如图:


JAVA个人通讯录的实现

图1.1 功能创新性成像

 

关系如图1.2:

JAVA个人通讯录的实现

图1.2数据库关系图

 

(3)软件实现相关功能的流程图

①登录窗体的实现如图1.3

JAVA个人通讯录的实现

                                                                                                                            图1.3登陆窗口实现

登录窗体中可以实现用户的登录和注册功能,当用户输入用户名和密码时点击“登录”按钮,然后调用数据库,若数据库中已有该用户且密码正确则登陆成功并进入主界面,否则重新提示“用户名错误或密码错误”。当点击“注册”按钮时,调用数据库,若已有相同用户则提示“”已注册,清空文本框;若数据库中没有该用户则存入该用户信息到数据库中。

②主窗体实现如图1.4

在主窗体中可以实现以下功能,用户联系人的新增、删除、修改和搜索联系人信息

JAVA个人通讯录的实现

图1.4主窗体实现

 

算法分析

Login类

这个类主要实现的是登入窗口的方法,在主窗体里设置了两个文本框用于获得用户名和密码。然后设置两个按钮分别是登陆和注册。关于登陆按钮会先检查二个文本框是否为空,如果是就报错否则调用access数据库查询是否信息正确。关于注册按钮,当用户名密码不为空的时候,检测数据库里没有同名联系人的情况下将新建一个账号。

MainFram类

这个类是通讯录的主窗口,这个类定义了许多文本框和按钮分别储存显示用户当前联系人的编号、姓名、性别、年龄、电话、Email、邮编、传真、地址、所属分组、照片和备注。还有许多按钮我们为其增加了相应的监听来完成不同的需求。

新增按钮:点击将会把模式切换到新增,在点击保存的时候会有所改变。

搜索按钮:当前支持两种模式的查询一个是编号,一个是姓名。点击后调用sql语句对数据库进行访问,如果存在该联系人通过setInfo(DBUtil.getPerInfo());的方法从数据库中获得消息然后再把消息显示在信息面板中否则提示没有该联系人。

添加分组按钮:点击后会弹出对话框,输入想要添加的分组,如果有就提示错误否则进一步确认然后添加新的分组。

删除分组按钮:点击后会提醒是否删除,确认后会调用sql语言访问数据库删除lxy表中所有含当前分组的联系人。

浏览按钮:点击浏览按钮会弹出一个新窗口可以访问本机文件,具体情况在Browse_pictures类里在做解释。

保存按钮:点保存按钮会先判断当前模式,如果是新增就把从信息面板中的获得的信息在数据库中新建记录,如果是修改的话就会先找到联系人然后再数据库里更新其信息。

删除按钮:点击会先弹出窗口寻求确认,确认后会调用sql语句把当前面板的联系人删除。

其他重要的变量和方法:

public static String picPath :表示当前联系人的照片的绝对路径。

public static String nowID :表示当前的联系人id用于类外调用。

public void iniTopPanel(); 上面板的初始化

public void iniBelowPanel(); 下面板的初始化

public void iniPhoPanel(); 照片面板的设置

public void actionPerformed(); 为每个按钮注册监听器

public void clearInfo(); 清空信息面板

public voidsetInfo(Vector<String>pInfo); 将信息向量设置到信息面板中

public voidgetInfo(Vector<String>pInfo); 从信息面板中获得信息向量

public setPic(String pid);设置个人图像从数据库中获得当前联系人照片的绝对路径然后显示出来

public void getnowID(); 获得当前用户编号

              3.DBUtil类

                     这个类是连接数据库和调用数据库,我们采用Access数据库。

              首先是连接到数据库的方式有两种,一种是搭建ODBC数据源然后连接,另外一是通过直接路径直接连接。

              调用Class.forName(driver);driver=sun.jdbc.odbc.JdbcOdbcDriver;

       然后是声明数据库的引用DriverManager.getConnection(url);url=jdbc:odbc:driver={MicrosoftAccess Driver (*.mdb)};DBQ=path;其中path为数据库存放的绝对路径。

              然后是一些主要的方法:

              publicstatic Connection getConnection();连接数据库的方法就是上面描述一样

              publicstatic void closeCon(); 关闭数据库的连接

              publicstatic boolen check(String user,String pwd); 登录的验证判断用户名密码是否正确

              publicstatic int update(String sql); 根据传来的sql语句更新数据库

              publicstatic boolen isExist(String sql); 判断该记录是否存在

              publicstatic int delUser(String uid); 删除该用户

              publicstatic void delGroup(String user,String group); 删除分组返回删除的联系人个数

              publicstatic String insertPerson(String uid,Vector<String> pInfo);根据信息向量添加联系人

              publicstatic String updatePerson(String uid,Vector<String>pInfo);根据信息向量更新联系人

       publicstatic void updatePic(String sql,String photo); 更新照片的地址

       publicstatic Vector<String> getPerInfo(String sql); 获得联系人信息

       publicstatic String getPic(String sql); 得到照片

  4.Browse_pictures类

           该类是用于浏览电脑本地文件夹然后选择照片,当选择好照片后有两个按钮供选择。

              确定按钮:获得当前联系人id然后获得当前照片路径更新到数据库。

              取消按钮:取消当前的选择,返回通讯录界面。

 

3.软件和代码的实现  

(1)登陆窗口关键技术的实现 Login.java

  1. 1)登陆窗口关键技术的实现 Login.java
  2. /******* 确定按钮设置和监听事件 *********/
  3. btnInt.addActionListener(new ActionListener() {
  4. public void actionPerformed(ActionEvent e) {
  5. // 登录按钮响应事件
  6. String user = jbf.getText().trim();// 获得用户名
  7. String pwd = String.valueOf(jpf.getPassword());// 获得密码
  8. if (DBUtil.check(user, pwd)) {
  9. JOptionPane.showMessageDialog(null, "登入成功");
  10. MainFram mf = new MainFram(user);
  11. setVisible(false);
  12. } else {
  13. JOptionPane.showMessageDialog(null, "对不起用户名或密码错误");
  14. clear();
  15. }
  16. }
  17. });
  18. /************* 注册按钮设置和响应事件 ************/
  19. btnSin.addActionListener(new ActionListener() {
  20. public void actionPerformed(ActionEvent e) {
  21. // 注册按钮响应事件
  22. String user = jbf.getText().trim();// 获得用户名
  23. String pwd = String.valueOf(jpf.getPassword());// 获得密码
  24. String sql = "";// 声明sql语句
  25. if (user.equals("")) {
  26. JOptionPane.showMessageDialog(null, "用户名不能为空");
  27. } else if (pwd.equals("")) {
  28. JOptionPane.showMessageDialog(null, "密码不能为空");
  29. } else {
  30. sql = "select uid from user where uid='" + user + "'";
  31. if (DBUtil.isExist(sql)) {// 用户名已经存在
  32. JOptionPane.showMessageDialog(null, "对不起,用户名已存在!!!");
  33. clear();// 清空输入文本框
  34. } else {
  35. sql = "insert into user values('" + user + "','" + pwd
  36. + "')";
  37. if (DBUtil.update(sql) > 0) {// 注册成功
  38. JOptionPane.showMessageDialog(null,
  39. "恭喜您!!!注册成功,请登陆");
  40. clear();
  41. }
  42. }
  43. }
  44. }
  45. });
  46. }
  47. (2)主窗口关键技术的实现MainFram.java
  48. //窗体的初始化
  49. public void actionPerformed(ActionEvent e) {// 按钮注册事件的实现
  50. if (e.getSource() == jbtAdd) {
  51. monitorAddButton();
  52. } else if (e.getSource() == jbtSearch) {
  53. monitorSearchButton();
  54. } else if (e.getSource() == jbtAddGroup) {
  55. monitorAddGroupButton();
  56. } else if (e.getSource() == jbtDeleteGroup) {
  57. monitorDeleteGroupButton();
  58. } else if (e.getSource() == jbtBrowse) {
  59. monitorBrowseButton();
  60. } else if (e.getSource() == jbtSave) {
  61. monitorSaveButton();
  62. } else if (e.getSource() == jbtdelete) {
  63. monitorDelButton();
  64. }
  65. }
  66. public void clearInfo()// 清空信息面板
  67. {
  68. TFName.setText("");// 清空文本框
  69. TFAge.setText("");
  70. TFidentifier.setText("");
  71. TFTel.setText("");
  72. TFEmail.setText("");
  73. TFPostcode.setText("");
  74. TFAdress.setText("");
  75. TFFax.setText("");
  76. TFChImg.setText("");
  77. beizhuTA.setText("");
  78. JPimg.setIcon(null);// 清空图像
  79. jbtComboBox.setSelectedItem("其它");// 设置分组选择“其它分组”
  80. picPath = "";// 图片路径设置为空
  81. }
  82. public Vector<String> getInfo()// 从信息面板得到用户输入的信息
  83. {
  84. Vector<String> pInfo = new Vector<String>();
  85. pInfo.add(TFidentifier.getText().trim());// 编号
  86. pInfo.add(TFName.getText().trim());// 添加name
  87. String gender = RB_man.isSelected() ? "男" : "女";
  88. pInfo.add(gender);// 添加性别
  89. pInfo.add(TFAge.getText().trim());// 年龄
  90. pInfo.add(TFTel.getText().trim());// 电话号码
  91. pInfo.add(TFEmail.getText().trim());// Email
  92. pInfo.add((String) jbtComboBox.getSelectedItem());// 分组
  93. pInfo.add(TFPostcode.getText().trim());// 邮编
  94. pInfo.add(TFFax.getText());// 传真
  95. pInfo.add(beizhuTA.getText());// 备注
  96. pInfo.add(TFAdress.getText().trim());// 地址
  97. pInfo.add(TFName.getText().trim());// 名字
  98. String photoPath = picPath;// 得到照片路径
  99. pInfo.add(photoPath);// 照片路径
  100. return pInfo;
  101. }
  102. public void setInfo(Vector<String> pInfo) {
  103. // 将信息向量按规则填到信息面板里
  104. this.clearInfo();
  105. if (pInfo.size() == 0) {
  106. JOptionPane.showMessageDialog(this, "所查用户不存在!!!", "错误", JOptionPane.WARNING_MESSAGE);
  107. } else { // 显示联系姓名
  108. String out;
  109. out = pInfo.get(1);
  110. JOptionPane.showMessageDialog(null, out);
  111. TFidentifier.setText(pInfo.get(0));// 编号
  112. TFName.setText(pInfo.get(1));// 姓名
  113. if (pInfo.get(2).equals("男")) {// 显示性别
  114. RB_man.setSelected(true);
  115. } else {// 显示性别
  116. RB_femal.setSelected(true);
  117. }
  118. // 显示年龄、电话号码和电子邮件
  119. TFAge.setText(pInfo.get(3));
  120. TFTel.setText(pInfo.get(4));
  121. TFEmail.setText(pInfo.get(5));
  122. String group = pInfo.get(6);// 分组
  123. int group_number = jbtComboBox.getItemCount();// 分组个数
  124. boolean isExist = false;
  125. for (int i = 0; i < group_number && isExist; ++i) {
  126. if (group.equals((String) jbtComboBox.getItemAt(i))) {
  127. jbtComboBox.setSelectedItem(pInfo.get(6));// 设置分组信息
  128. isExist = true;
  129. }
  130. }
  131. if (!isExist) {// 初始化分组中不存在该分组
  132. jbtComboBox.addItem(group);// 添加分组
  133. jbtComboBox.setSelectedItem(pInfo.get(6));// 设置分组信息
  134. }
  135. // 显示邮编和地址
  136. TFPostcode.setText(pInfo.get(7));
  137. TFFax.setText(pInfo.get(8));// 传真
  138. beizhuTA.setText(pInfo.get(9));// 备注
  139. TFAdress.setText(pInfo.get(10));// 地址
  140. setPic(pInfo.get(0));// 设置图像为从数据库得到的图像
  141. }
  142. }
  143. public void setPic(String pid) {// 设置个人图像显示
  144. String sql = "select pphoto from lxy where pid='" + pid + "'";
  145. String Pic = DBUtil.getPic(sql);// 从数据库得到此人的图像
  146. if (Pic != null) {// 如果此联系人上传了图像
  147. picPath = Pic;
  148. JPimg.setIcon(new ImageIcon(Pic));// 将图像显示到JLabel
  149. JPimg.setHorizontalAlignment(JLabel.CENTER);// 设置图片水平居中显示
  150. JPimg.setVerticalAlignment(JLabel.CENTER);// 设置图片垂直方向居中显示
  151. } else {// 如果图像为空,则不显示
  152. JPimg.setIcon(null);
  153. }
  154. }
  155. public void monitorAddButton()// 监听新增按钮的方法
  156. {
  157. JOptionPane.showMessageDialog(null, "请输入信息后保存!");
  158. isInsert = true;
  159. clearInfo();
  160. };
  161. public void monitorSearchButton() {// 监听搜索按钮的方法
  162. String search = TFSearch.getText().trim();// 获得搜索框内容
  163. String mode = IDsearche.isSelected() ? "编号" : "姓名";
  164. String sql = "";// 声明查找字符串
  165. if (search.equals("")) {
  166. JOptionPane.showMessageDialog(this, "查找条件不能为空!!!", "错误", JOptionPane.WARNING_MESSAGE);
  167. } else {
  168. if (mode.equals("姓名")) {
  169. sql = "select pid,pname,pgender,page,pnumber,pemail,pgroup,ppostalcode,pfax,premarks,padress from lxy where uid='"
  170. + nowname + "'and pname='" + search + "'";
  171. } else {
  172. sql = "select pid,pname,pgender,page,pnumber,pemail,pgroup,ppostalcode,pfax,premarks,padress from lxy where uid='"
  173. + nowname + "'and pid='" + search + "'";
  174. }
  175. setInfo(DBUtil.getPerInfo(sql));// 设置信息面板为该联系人的信息
  176. }
  177. };
  178. public void monitorAddGroupButton() {// 监听添加分组按钮的方法
  179. String group = JOptionPane.showInputDialog(this, "请输入分组:", "添加分组", JOptionPane.PLAIN_MESSAGE);
  180. if (group != null) {// 当分组不为空的时候
  181. if (group.equals("")) {
  182. JOptionPane.showMessageDialog(this, "分组名字不能为空", "错误", JOptionPane.WARNING_MESSAGE);
  183. } else {
  184. int group_number = jbtComboBox.getItemCount();// 分组个数
  185. // JOptionPane.showMessageDialog(this,"分组有"+group_number+"个","错误",JOptionPane.WARNING_MESSAGE);
  186. for (int i = 0; i < group_number; ++i) {
  187. if (group.equals((String) jbtComboBox.getItemAt(i))) {// 分组已存在,直接返回
  188. JOptionPane.showMessageDialog(this, "分组已存在", "错误", JOptionPane.WARNING_MESSAGE);
  189. return;
  190. }
  191. }
  192. jbtComboBox.addItem(group);// 添加分组
  193. JOptionPane.showMessageDialog(this, "分组添加成功", "提示", JOptionPane.WARNING_MESSAGE);// 添加分组成功
  194. jbtComboBox.setSelectedItem(group);// 选中当前分组
  195. }
  196. }
  197. };
  198. public void monitorDeleteGroupButton() {// 监听删除分组按钮的方法
  199. int select = JOptionPane.showConfirmDialog(this, "删除分组将会删除" + "分组里的所有联系人!!!是否删除?", "确认",
  200. JOptionPane.YES_NO_OPTION);
  201. if (select == JOptionPane.YES_OPTION) {// 确定删除联系人
  202. String group = (String) jbtComboBox.getSelectedItem();
  203. DBUtil.delGroup(nowname, group);// 从数据库中删除
  204. jbtComboBox.removeItem((String) jbtComboBox.getSelectedItem());// 从下拉列表中删除
  205. JOptionPane.showMessageDialog(this, "删除分组成功", "消息", JOptionPane.INFORMATION_MESSAGE);
  206. }
  207. clearInfo();
  208. };
  209. public void monitorBrowseButton() {// 监听浏览按钮的方法
  210. getnowID();
  211. EventQueue.invokeLater(new Runnable() {
  212. @Override
  213. public void run() {
  214. // TODO Auto-generated method stub
  215. JFrame frame = new Browse_pictures();
  216. frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  217. frame.setVisible(true);
  218. }
  219. });
  220. };
  221. public void monitorSaveButton() {// 监听保存按钮的方法
  222. String mode;
  223. if (isInsert)
  224. mode = "添加";
  225. else
  226. mode = "修改";
  227. JOptionPane.showMessageDialog(this, mode, mode, JOptionPane.WARNING_MESSAGE);
  228. String pid = TFidentifier.getText().trim();// 得到联系人的编号
  229. String pname = TFName.getText().trim();// 得到联系人的姓名
  230. String sqla = "select * from lxy where pid='" + pid + "'";// 判断此编号是否存在的SQL
  231. String sqlb = "select * from lxy where pname='" + pname + "'";// 判断此姓名是否存在的SQL
  232. boolean isIdExist = DBUtil.isExist(sqla);// 得到编号是否存在
  233. boolean isNameExist = DBUtil.isExist(sqlb);// 得到姓名是否存在
  234. String perNameAfter = TFName.getText().trim();// 得到修改后联系人的名字
  235. if (!(pid.equals("") || pname.equals(""))) {
  236. if (isInsert) {// 是添加的话
  237. JOptionPane.showMessageDialog(null, "现在开始添加");
  238. if (!(pid.equals("") || pname.equals(""))) {// 得到插入的图片路径是否合法的判断字符串
  239. String s = DBUtil.insertPerson(nowname, getInfo());
  240. if (s.equals("isNull")) {
  241. JOptionPane.showMessageDialog(this, "图像路径不合法" + "添加联系人失败", "错误", JOptionPane.WARNING_MESSAGE);
  242. }
  243. } else {// 用户名或者ID已经存在
  244. JOptionPane.showMessageDialog(this, "联系人ID或者姓名已经存在", "错误", JOptionPane.WARNING_MESSAGE);
  245. }
  246. } else {// 编辑联系人资料
  247. JOptionPane.showMessageDialog(null, "现在开始修改");
  248. if (isIdExist) {// ID没变进行更新
  249. String s = DBUtil.updatePerson(nowname, getInfo());
  250. if (s.equals("isNull")) {
  251. JOptionPane.showMessageDialog(this, "图像路径不合法" + "添加联系人失败", "错误", JOptionPane.WARNING_MESSAGE);
  252. }
  253. }
  254. if (!isIdExist) {// ID变了
  255. if (!isNameExist) {// 名字也变了就执行插入动作
  256. String s = DBUtil.insertPerson(nowname, this.getInfo());
  257. if (!s.equals("isNull")) {// 在树上添加节点 此为合法的文件路径
  258. // this.addPerNode(perNameAfter,perGroupAfter);
  259. } else {
  260. JOptionPane.showMessageDialog(this, "图像路径不合法" + "添加联系人失败", "错误",
  261. JOptionPane.WARNING_MESSAGE);
  262. }
  263. } else {
  264. JOptionPane.showMessageDialog(null, "重新插入此人信息");
  265. DBUtil.update("delete from lxy where pname='" + perNameAfter + "'");
  266. DBUtil.insertPerson(nowname, this.getInfo());// 重新插入此人记录
  267. }
  268. }
  269. }
  270. } else {// 为空
  271. JOptionPane.showMessageDialog(this, "联系人ID或者姓名不能为空", "错误", JOptionPane.WARNING_MESSAGE);
  272. return;
  273. }
  274. isInsert = false;
  275. }
  276. public void monitorDelButton()// 监听删除按钮的方法
  277. {
  278. String pid = TFidentifier.getText();
  279. // 弹出删除对话框
  280. int index = JOptionPane.showConfirmDialog(this, "是否删除?y/n", "确认对话框", JOptionPane.YES_NO_OPTION,
  281. JOptionPane.QUESTION_MESSAGE);
  282. if (index == 0) {// 确认删除
  283. String sqlb = "delete from lxy where pid='" + pid + "'";
  284. int i = DBUtil.update(sqlb);// 删除联系人信息
  285. if (i != -1) {// 删除成功对话框
  286. JOptionPane.showMessageDialog(this, "删除成功", "删除", JOptionPane.INFORMATION_MESSAGE);
  287. clearInfo();
  288. }
  289. }
  290. }
  291. public void getnowID() {// 获得当前用户编号
  292. nowID = TFidentifier.getText().trim();
  293. }
  294. }
  295. (3)浏览按钮功能的实现(修改头像方法)
  296. class Browse_pictures extends JFrame {
  297. JPanel buttonPanel = new JPanel();// 按钮面板
  298. JButton jbmakesure = new JButton("确定");
  299. JButton jbcanel = new JButton("取消");
  300. public Browse_pictures() {
  301. setTitle("ImageViewer");
  302. setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
  303. setLocationRelativeTo(null);
  304. label = new JLabel();
  305. add(label);
  306. chooser = new JFileChooser();
  307. chooser.setCurrentDirectory(new File("."));
  308. JMenuBar menubar = new JMenuBar();
  309. setJMenuBar(menubar);
  310. JMenu menu = new JMenu("File");
  311. menubar.add(menu);
  312. JMenuItem openItem = new JMenuItem("Open");
  313. menu.add(openItem);
  314. JMenuItem exitItem = new JMenuItem("Close");
  315. menu.add(exitItem);
  316. buttonPanel.add(jbmakesure);
  317. buttonPanel.add(jbcanel);
  318. jbmakesure.addActionListener(new ActionListener() {// 确定按钮监听
  319. public void actionPerformed(ActionEvent arg0) {
  320. int index = JOptionPane.showConfirmDialog(null, "是否修改图片?y/n", "确认对话框", JOptionPane.YES_NO_OPTION,
  321. JOptionPane.QUESTION_MESSAGE);
  322. if (index == 0) {// 确认修改
  323. String id = MainFram.nowID;
  324. String sql = "update lxy set pphoto=? where pid='" + id + "'";
  325. String photo = chooser.getSelectedFile().getPath();
  326. DBUtil.updatePic(sql, photo);
  327. MainFram.picPath = photo;
  328. MainFram.JPimg.setIcon(new ImageIcon(photo));// 将图像显示到JLabel
  329. MainFram.JPimg.setHorizontalAlignment(JLabel.CENTER);// 设置图片水平居中显示
  330. MainFram.JPimg.setVerticalAlignment(JLabel.CENTER);// 设置图片垂直方向居中显示
  331. }
  332. }
  333. });
  334. jbcanel.addActionListener(new ActionListener() {// 取消事件监听
  335. @Override
  336. public void actionPerformed(ActionEvent arg0) {
  337. dispose();
  338. }
  339. });
  340. openItem.addActionListener(new ActionListener() {
  341. @Override
  342. public void actionPerformed(ActionEvent arg0) {
  343. // TODO Auto-generated method stub
  344. int result = chooser.showOpenDialog(null);
  345. if (result == JFileChooser.APPROVE_OPTION) {
  346. String name = chooser.getSelectedFile().getPath();
  347. label.setIcon(new ImageIcon(name));
  348. // 显示按钮面板
  349. add(buttonPanel, BorderLayout.SOUTH);
  350. }
  351. }
  352. });
  353. exitItem.addActionListener(new ActionListener() {
  354. @Override
  355. public void actionPerformed(ActionEvent arg0) {
  356. // TODO Auto-generated method stub
  357. setVisible(false);
  358. }
  359. });
  360. }
  361. private JLabel label;
  362. private JFileChooser chooser;
  363. private static final int DEFAULT_WIDTH = 300;
  364. private static final int DEFAULT_HEIGHT = 400;
  365. }
  366. (4)数据库的使用的实现
  367. public class DBUtil {
  368. private static String driver = "sun.jdbc.odbc.JdbcOdbcDriver";// 声明驱动类字符串
  369. private static String url = "jdbc:odbc:driver={Microsoft Access Driver (*.mdb)};DBQ=db\\linkman.mdb";// 声明数据库连接字符串
  370. private static Connection con = null;// 数据库连接引用
  371. private static Statement stat = null;// 语句引用
  372. private static PreparedStatement psInsert = null;// 预编译语句引用
  373. private static ResultSet rs = null;// 结果及对象的引用
  374. public static Connection getConnection() {// 连接数据库的方法
  375. try {
  376. Class.forName(driver);
  377. con = DriverManager.getConnection(url);
  378. } catch (Exception e) {
  379. System.out.println("连接失败!");
  380. e.printStackTrace();
  381. }
  382. return con;// 返回连接
  383. }
  384. public static void closeCon() {// 关闭数据库连接的方法
  385. try {
  386. if (rs != null) {
  387. rs.close();
  388. rs = null;
  389. }
  390. if (stat != null) {
  391. stat.close();
  392. stat = null;
  393. }
  394. if (con != null) {
  395. con.close();
  396. con = null;
  397. }
  398. } catch (Exception e) {
  399. e.printStackTrace();
  400. }
  401. }
  402. public static boolean check(String user, String pwd) {// 登陆验证
  403. boolean flag = false;
  404. try {
  405. con = DBUtil.getConnection();// 得到数据库连接
  406. stat = con.createStatement();// 创建语句对象
  407. rs = stat.executeQuery("select pwd from user where uid='" + user + "'");
  408. rs.next();
  409. String mywd = rs.getString(1);// 得到密码
  410. if (mywd.equals(pwd)) {
  411. flag = true;// 密码正确
  412. }
  413. } catch (Exception e) {
  414. flag = false;// 有异常登录失败
  415. } finally {
  416. DBUtil.closeCon();// 关闭数据库
  417. }
  418. return flag;
  419. }
  420. public static int update(String sql) {// 更新数据库
  421. int res = 0;// 返回值
  422. try {
  423. con = DBUtil.getConnection();// 连接到数据库
  424. stat = con.createStatement();// 创建语句对象
  425. res = stat.executeUpdate(sql);// 更新
  426. } catch (Exception e) {
  427. e.printStackTrace();// 异常输出
  428. res = -1;// 返回值为负一
  429. }
  430. finally {
  431. DBUtil.closeCon();// 关闭数据库
  432. }
  433. return res;
  434. }
  435. public static boolean isExist(String sql) {// 判断是否存在该记录
  436. boolean flag = false;
  437. try {
  438. con = DBUtil.getConnection();// 连接数据库
  439. stat = con.createStatement();// 创建语句对象
  440. rs = stat.executeQuery(sql);// 查询
  441. if (rs.next()) {
  442. flag = true;// 存在
  443. }
  444. } catch (Exception e) {
  445. e.printStackTrace();
  446. flag = false;
  447. } finally {
  448. DBUtil.closeCon();
  449. }
  450. return flag;
  451. }
  452. public static int delUser(String uid) {// 删除用户
  453. int res = 0;
  454. Vector<String> mypid = new Vector<String>();// 用于存放用户联系人的向量集合
  455. try {
  456. con = DBUtil.getConnection();// 连接数据库
  457. stat = con.createStatement();// 创建语句对象
  458. rs = stat.executeQuery("select pid from lxy where uid='" + uid + "'");// 得到联系人id
  459. while (rs.next()) {
  460. String myid = rs.getString(1);
  461. mypid.add(myid);
  462. }
  463. stat = con.createStatement();// 创建语句对象
  464. res = stat.executeUpdate("delete from lxy where uid='" + uid + "'");// 从lxy表中删除每个联系人
  465. stat.executeUpdate("delete from user where uid='" + uid + "'");// 从use表中删除用户
  466. } catch (Exception e) {
  467. e.printStackTrace();
  468. } finally {
  469. DBUtil.closeCon();// 关闭数据库
  470. }
  471. return res;// 返回删除多少联系人
  472. }
  473. public static void delGroup(String user, String group) {// 删除分组,返回联系人的个数
  474. try {
  475. con = DBUtil.getConnection();// 连接数据库
  476. stat = con.createStatement();// 创建语句对象
  477. rs = stat.executeQuery("select pid from lxy where pgroup='" + group + "'" + "and uid='" + user + "'");// 从数据库中搜索group的pid
  478. stat = con.createStatement();// 创建语句对象
  479. stat.executeUpdate("delete from lxy where pgroup='" + group + "'");
  480. } catch (Exception e) {
  481. e.printStackTrace();// 打印异常信息
  482. } finally {
  483. DBUtil.closeCon();// 关闭数据库连接
  484. }
  485. }
  486. public static String insertPerson(String uid, Vector<String> pInfo) {// 添加联系人
  487. String isPathNull = "isNotNull";// 图像是否合法
  488. try {
  489. con = DBUtil.getConnection();// 连接数据库
  490. if (pInfo.get(11).equals("") || pInfo.get(11) == null) {// 路径为空
  491. psInsert = con.prepareStatement(
  492. "insert into lxy(pid,pname,pgender,page,pnumber,pemail,pgroup,ppostalcode,pfax,premarks,padress,uid)values(?,?,?,?,?,?,?,?,?,?,?,?)");
  493. } else {
  494. psInsert = con.prepareStatement(
  495. "insert into lxy(pid,pname,pgender,page,pnumber,pemail,pgroup,ppostalcode,pfax,premarks,padress,uid,pphoto)values(?,?,?,?,?,?,?,?,?,?,?,?,?)");
  496. psInsert.setString(13, pInfo.get(12));// 设置pphoto参数的数据
  497. }
  498. for (int i = 0; i < 11; i++) {// 设置公共信息
  499. psInsert.setString(i + 1, pInfo.get(i));
  500. }
  501. psInsert.setString(12, uid);// 用户
  502. psInsert.execute();// 执行更新
  503. psInsert.close();// 关闭语句
  504. } catch (Exception e) {
  505. e.printStackTrace();// 打印错误信息
  506. } finally {
  507. DBUtil.closeCon();// 关闭数据库
  508. }
  509. return isPathNull;
  510. }
  511. public static String updatePerson(String uid, Vector<String> pInfo) {// 更新联系人
  512. String isPathNull = "isNotNull";// 图像是否合法
  513. try {
  514. con = DBUtil.getConnection();// 连接数据库
  515. if (pInfo.get(11).equals("") || pInfo.get(11) == null) {// 路径为空
  516. System.out.println("rujinweikon");
  517. psInsert = con.prepareStatement(
  518. "update lxy set pname=?,pgender=?,page=?,pnumber=?,pemail=?,pgroup=?,ppostalcode=?,pfax=?,premarks=?,padress=?,uid=? where pid='"
  519. + pInfo.get(0).trim() + "'");
  520. } else {
  521. psInsert = con.prepareStatement(
  522. "update lxy set pname=?,pgender=?,page=?,pnumber=?,pemail=?,pgroup=?,ppostalcode=?,pfax=?,premarks=?,padress=?,uid=?,pphoto=? where pid='"
  523. + pInfo.get(0).trim() + "'");
  524. psInsert.setString(12, pInfo.get(11));// 设置pphoto参数的数据
  525. }
  526. for (int i = 0; i < 10; i++) {// 设置公共信息
  527. psInsert.setString(i + 1, pInfo.get(i + 1));
  528. }
  529. System.out.println(uid);
  530. psInsert.setString(11, uid);// 用户
  531. psInsert.execute();// 执行更新
  532. psInsert.close();// 关闭语句
  533. } catch (Exception e) {
  534. e.printStackTrace();// 打印错误信息
  535. } finally {
  536. DBUtil.closeCon();// 关闭数据库
  537. }
  538. return isPathNull;
  539. }
  540. public static void updatePic(String sql, String photo) {
  541. try {
  542. con = DBUtil.getConnection();// 连接数据库
  543. stat = con.createStatement();// 创建语句对象
  544. psInsert = con.prepareStatement(sql);
  545. psInsert.setString(1, photo);
  546. psInsert.execute();// 执行更新
  547. psInsert.close();// 关闭语句
  548. } catch (Exception e) {
  549. e.printStackTrace();// 打印错误信息
  550. } finally {
  551. DBUtil.closeCon();// 关闭数据库
  552. }
  553. }
  554. public static Vector<String> getPerInfo(String sql) {// 得到联系人信息
  555. Vector<String> pInfo = new Vector<String>();
  556. try {
  557. con = DBUtil.getConnection();// 连接到数据库
  558. stat = con.createStatement();// 创建语句对象
  559. rs = stat.executeQuery(sql);// 查询
  560. while (rs.next()) {
  561. for (int i = 1; i < 12; ++i) {
  562. pInfo.add(rs.getString(i));// 添加到返回集合
  563. }
  564. }
  565. } catch (Exception e) {
  566. e.printStackTrace();// 打印异常消息
  567. } finally {
  568. DBUtil.closeCon();// 关闭数据库
  569. }
  570. return pInfo;
  571. }
  572. public static String getPic(String sql) {// 得到照片
  573. String resPic = "";
  574. try {
  575. con = DBUtil.getConnection();// 连接到数据库
  576. stat = con.createStatement();// 创建语句对象
  577. rs = stat.executeQuery(sql);// 执行sql语句
  578. if (rs.next()) {
  579. resPic = rs.getString(1);
  580. }
  581. } catch (Exception e) {
  582. e.printStackTrace();// 打印异常信息
  583. } finally {
  584. DBUtil.closeCon();// 关闭数据库
  585. }
  586. return resPic;
  587. }
  588. public static void main(String[] args) {// 主方法
  589. System.out.println(DBUtil.delUser("aa"));
  590. }
  591. }


4.软件测试

(1)注册和登陆功能的实现,如图1.5

JAVA个人通讯录的实现JAVA个人通讯录的实现

图1.5注册和登陆功能的实现

(2)登陆成功,如图1.6


图1.6 登陆成功

(3)修改头像,如图1.7

JAVA个人通讯录的实现              JAVA个人通讯录的实现

图1.7 修改头像

5.参考材料和文献

《java语言程序设计-基础版》

《Java开发手册》

6. 总结与体会、意见和建议

       通过对人们日常生活细心观察,能很好地发现人们的需求,这就为我们开发一款软件提供了思想。第一步,开发软件首先要做的就是软件分析,从人们的日常需求来确定软件的功能。第二步,确定好了软件的功能后就是要实现具体的功能,为了降低软件开发难度和提高开发进度,可把要实现的功能模块化,然后再一步步实现各功能的细节。第三部,就是软件地测试,测试软件就是找到软件地错误和不足,并加以修改,已达到预期的效果。
个人总结:数据库好坑!

7. 软件使用

软件使用流程为:1、注册2、登陆3、填写信息,保存4、按照编号或者姓名搜索       5、找到联系人后修改图片、保存。

8.小组成员的信息

王争取   TEL:17862810568        Email:[email protected]

张鹏       TEL:17862810957        Email:[email protected] @[TOC](这里写自定义目录标题)

欢迎使用Markdown编辑器

你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。

新的改变

我们对Markdown编辑器进行了一些功能拓展与语法支持,除了标准的Markdown编辑器功能,我们增加了如下几点新功能,帮助你用它写博客:

  1. 全新的界面设计 ,将会带来全新的写作体验;
  2. 在创作中心设置你喜爱的代码高亮样式,Markdown 将代码片显示选择的高亮样式 进行展示;
  3. 增加了 图片拖拽 功能,你可以将本地的图片直接拖拽到编辑区域直接展示;
  4. 全新的 KaTeX数学公式 语法;
  5. 增加了支持甘特图的mermaid语法1 功能;
  6. 增加了 多屏幕编辑 Markdown文章功能;
  7. 增加了 焦点写作模式、预览模式、简洁写作模式、左右区域同步滚轮设置 等功能,功能按钮位于编辑区域与预览区域中间;
  8. 增加了 检查列表 功能。

功能快捷键

撤销:Ctrl/Command + Z
重做:Ctrl/Command + Y
加粗:Ctrl/Command + B
斜体:Ctrl/Command + I
标题:Ctrl/Command + Shift + H
无序列表:Ctrl/Command + Shift + U
有序列表:Ctrl/Command + Shift + O
检查列表:Ctrl/Command + Shift + C
插入代码:Ctrl/Command + Shift + K
插入链接:Ctrl/Command + Shift + L
插入图片:Ctrl/Command + Shift + G

合理的创建标题,有助于目录的生成

直接输入1次#,并按下space后,将生成1级标题。
输入2次#,并按下space后,将生成2级标题。
以此类推,我们支持6级标题。有助于使用TOC语法后生成一个完美的目录。

如何改变文本的样式

强调文本 强调文本

加粗文本 加粗文本

标记文本

删除文本

引用文本

H2O is是液体。

210 运算结果是 1024.

插入链接与图片

链接: link.

图片: JAVA个人通讯录的实现

带尺寸的图片: JAVA个人通讯录的实现

居中的图片: JAVA个人通讯录的实现

居中并且带尺寸的图片: JAVA个人通讯录的实现

当然,我们为了让用户更加便捷,我们增加了图片拖拽功能。

如何插入一段漂亮的代码片

博客设置页面,选择一款你喜欢的代码片高亮样式,下面展示同样高亮的 代码片.

// An highlighted block
var foo = 'bar';

生成一个适合你的列表

  • 项目
    • 项目
      • 项目
  1. 项目1
  2. 项目2
  3. 项目3
  • 计划任务
  • 完成任务

创建一个表格

一个简单的表格是这么创建的:

项目 Value
电脑 $1600
手机 $12
导管 $1

设定内容居中、居左、居右

使用:---------:居中
使用:----------居左
使用----------:居右

第一列 第二列 第三列
第一列文本居中 第二列文本居右 第三列文本居左

SmartyPants

SmartyPants将ASCII标点字符转换为“智能”印刷标点HTML实体。例如:

TYPE ASCII HTML
Single backticks 'Isn't this fun?' ‘Isn’t this fun?’
Quotes "Isn't this fun?" “Isn’t this fun?”
Dashes -- is en-dash, --- is em-dash – is en-dash, — is em-dash

创建一个自定义列表

Markdown
Text-to-HTML conversion tool
Authors
John
Luke

如何创建一个注脚

一个具有注脚的文本。2

注释也是必不可少的

Markdown将文本转换为 HTML

KaTeX数学公式

您可以使用渲染LaTeX数学表达式 KaTeX:

Gamma公式展示 Γ(n)=(n1)!nN\Gamma(n) = (n-1)!\quad\forall n\in\mathbb N 是通过欧拉积分

Γ(z)=0tz1etdt&ThinSpace;. \Gamma(z) = \int_0^\infty t^{z-1}e^{-t}dt\,.

你可以找到更多关于的信息 LaTeX 数学表达式here.

新的甘特图功能,丰富你的文章

Mon 06Mon 13Mon 20已完成 进行中 计划一 计划二 现有任务Adding GANTT diagram functionality to mermaid
  • 关于 甘特图 语法,参考 这儿,

UML 图表

可以使用UML图表进行渲染。 Mermaid. 例如下面产生的一个序列图::

张三李四王五你好!李四, 最近怎么样?你最近怎么样,王五?我很好,谢谢!我很好,谢谢!李四想了很长时间,文字太长了不适合放在一行.打量着王五...很好... 王五, 你怎么样?张三李四王五

这将产生一个流程图。:

链接
长方形
圆角长方形
菱形
  • 关于 Mermaid 语法,参考 这儿,

FLowchart流程图

我们依旧会支持flowchart的流程图:

Created with Raphaël 2.2.0开始我的操作确认?结束yesno
  • 关于 Flowchart流程图 语法,参考 这儿.

导出与导入

导出

如果你想尝试使用此编辑器, 你可以在此篇文章任意编辑。当你完成了一篇文章的写作, 在上方工具栏找到 文章导出 ,生成一个.md文件或者.html文件进行本地保存。

导入

如果你想加载一篇你写过的.md文件或者.html文件,在上方工具栏可以选择导入功能进行对应扩展名的文件导入,
继续你的创作。


  1. mermaid语法说明 ↩︎

  2. 注脚的解释 ↩︎