1、 淮 海 工 学 院 计算机工程学院课程设计报告设计名称: 面向对象课程设计 选题名称: 基于C/S的图书查询系统的实现 姓 名: 学 号: 专业班级: 系 (院): 计算机工程学院 设计时间: 2014.3.122014.4.10 设计地点: 软件实验室、教室 成绩:指导教师评语: 签名: 年 月 日面向对象课程设计报告 第 46 页,共 46 页1课程设计目的面向对象程序设计是一门实践性很强的计算机专业基础课程,课程设计是学习完该课程后进行的一次较全面的综合练习。其目的在于通过实践加深学生对面向对象程序设计的理论、方法和基础知识的理解,掌握使用Java语言进行面向对象设计的基本方法,提高运
2、用面向对象知识分析实际问题、解决实际问题的能力。2课程设计任务与要求:课程设计可选用NetBeans、Eclipse、JBuilder等作为开发平台以提高开发效率,尽可能熟练掌握其中一种集成开发环境。建议采用UML建模技术进行系统的分析设计,在Visio中画出系统用例图和类图,并将UML图复制到设计报告中。通过这次设计,要求掌握以下内容:1) 面向对象技术中的继承与多态(重载和覆盖)机制、各种修饰符的使用2) 类、包、接口的定义与使用3) 常用工具类与算法的实现(数组、向量、字符串、链表)4) Java常用标准GUI组件及其事件处理5) Java的异常处理机制6) Java的数据库连接技术7)
3、 Java的多线程技术与动画制作8) Java的网络编程设计选题:基于C/S的图书查询系统的实现 包括客户端程序和服务器端程序。客户端程序向服务器端提出请求:比如提供图书的作者名,服务器端收到后,在数据库系统中查询到相关信息,发回客户端。3课程设计说明书一、 需求分析基于C/S的图书查询系统的开发目的是为了提高查询效率。选用Java开发工具可以提高查询系统的移植性和兼容性。系统主要功能是实现读者对图书信息进行准确、快速查阅。因此系统主要针对以下四方面的需求进行设计:1. 图书信息管理:涉及图书基本信息的添加、删除、修改;读者可以根据书名、作者、出版社、书号等关键字检索所需要的图书2. 读者信息
4、管理:涉及读者基本信息的录入、修改、删除;可以根据读者的证号、姓名等信息查询到读者,读者登录到系统后能够修改自己的联系方式等信息3. 借书还书管理:实现图书的借还功能,根据读者借书证号和书号将图书借给读者,根据图书条形码归还图书。 4. 系统信息管理:涉及管理员用户与系统参数的管理和维护,如设置图书的借期、数量、超期每天罚款金额等 二、概要设计 1、系统结构 基于C/S的图书查询系统分为服务器和客户端两个部分。服务器负责监听客户请求,如提供图书的作者名等,并将查询的结果通过网络发回客户端。而客户端主要负责构建图形用户界面,编写事件处理方法,在事件处理的方法体中发送请求并接收服务器端传来的数据。
5、 系统采用C/S结构,利用服务器和客户端的Socket通信机制完成信息的传递,数据库用来统计图书信息,因为主要涉及信息表格,所以选用Access实现数据库功能。因此系统总共由服务器、客户端和数据库三部分组成。2、各模块设计a)服务器(1)创建一个等待连接的ServerSocket对象。 (2)调用ServerSocket对象的accept()方法侦听接受客户端的连接请求。当侦听到一个客户的请求时,连接成功,并返回一个Socket对象。 (3)创建与Socket对象绑定的输入输出流,并建立相应的数据输入输出流。 (4)通过数据输入输出流与客户端进行数据读写,完成双向通信。 (5)当客户端断开连接
6、时,关闭各个流对象,结束通信。该部分主要由Server、ServerThread和GetConnection3个类组成。b)客户端(1)创建指定服务器上指定端口号的Socket对象。 (2)创建与Socket对象绑定的输入输出流,并建立相应的数据输入输出流。 (3)通过数据输入输出流与服务器端进行数据读写,完成双向通信。 (4)通过调用close()方法关闭与服务器端的连接,并关闭各个流对象,结束通信。 该部分由Client、login、BookRetrieve、SocketIO、add_book、del_book、add_user、view_user、del_user、ManagerFram
7、e10个类组成。c)Access数据库 建立Access数据库“图书信息”,在其中建立数据表“图书信息表”、“user” 等表,分别用于存放图书信息、用户信息等。 向表中录入适量数据,然后配置ODBC数据源“bookinfo”,与图书信息数据库建立关联,以便在程序中通过JDBC-ODBC桥来访问数据。登录删除图书添加图书查询图书管理员一般用户删除图书增加用户查询用户描述系统功能的用例图二、 详细设计由于本系统将通过具有各功能的类来实现各方面需求以及各模块的作用,所以接下来先介绍各类的详细设计。1、各类设计1)Server类 服务器模块主要通过这个类来实现,因此Server类为服务器端的主控类,
8、包括main()方法。为了能更好地与客户端建立连接和进行通信,需要在main()方法中创建ServerSocket对象,来监听来自客户端的连接和通信请求。类图: 2)ServerThread类 即线程类Thread的子类,主要负责服务器端与客户端的通信连接和数据传输,必要时保存数据查询结果。A. ServerThread类的主要成员变量a) s为Socket类的对象,其值从Server对象传入,该变量负责与客户端的通信连接。b) in为DataInputStream的对象,用其readUTF()方法接受来自客户端的数据。c) out为DataOutputStream的对象,用其writeUTF
9、()方法将数据发回客户端。d) con为Connection的对象,用于建立与数据源的连接。e) rs为ResultSet的对象,用于保存服务器端的数据查询结果。B. ServerThread类的主要方法a) ServerThread()为构造方法,用来初始化s,并创建in、out和con成员变量。b) run()方法为ServerThread类实现多线程的方法。通过Socket对象s,借助于输入、输出流对象in、out,完成接收客户端的数据请求,并在服务器端进行JDBC数据访问,然后将处理结果发送给客户端。 类图: 3)GetConnection类 利用该类对与数据源的连接信息进行封装。主要
10、负责通过JDBC来建立数据库的连接。A. GetConnection类的成员变量a) url是字符串变量,保存JDBC协议的URL信息。b) Driver是字符串变量,保存JDBC驱动程序名称的信息。c) con是Connection的对象,用于建立数据库的连接。B. GetConnection类的方法a) GetConnection()是构造方法,用来创建con对象。b) getConnection类是成员方法,用来返回con对象。类图: 4)SocketIO类 通过该类完成在客户端程序中与服务器端进行数据传输。A. SocketIO类的成员变量a) s是Socket的对象,用于和服务器端进
11、行套接字连接。b) in是DataInputStream对象,用于读取服务器端发来的数据。c) out是DataOutputStream对象,用于向服务器端发送数据。B. SocketIO类的方法a) SocketIO()是构造方法,用来创建s、in、out对象。b) getIn()是成员方法,用来返回in对象。c) getOut()是成员方法,用来返回out对象。类图:5)Client类该类是客户端的主控类,其中包括main()方法,在main()方法中创建login对象类图:6)login类 该类为JFrame的子类,实现ActionListener和ItemListener接口。主要实现
12、用户登录的交互界面。A. login类的成员变量a) lbl-pic是用于显示图像的标签,lbl-uid、lbl-pwd分别是提示输入账号和密码的标签。b) txt-uid和txt-pwd分别用于输入账号和密码。c) btn-ok和btn-cannel分别是“确定”和“取消”按钮。d) rb-user、rb-manager是用于表示用户类型的单选钮,rb-group用于对这两者进行成组。e) in和out分别用于输入,输出流操作。f) userType用来表示拥护的类型,即一般用户或管理员。B. login类的方法a) login()是构造方法,用来创建成员变量,并注册监听器。b) itemS
13、tateChanged()是rb-user和rb-manager的事件处理方法。c) actionPerformed()用来将登陆请求发送到服务器端验证,并接受服务器端的返回结果。类图: 7)BookRetrieve类 该类为JFrame的子类并实现ActionListener和ItemListener接口。主要负责图书信息的查询,如提供图书的作者名等。A. BookRetrieve类的成员变量a) lbl-opt和lbl-info用于显示提示信息。b) choice是Choice类型的对象,用于存放查询选项,如“书名”、“作者”、“出版社”等。c) showResult是JTextArea类
14、型的对象,用于显示服务器端返回的查询结果。d) choiceName用于返回choice中的选中项。e) in和out分别用于输入、输出流操作。f) send按钮用于触发actionPerformed事件处理方法。B. BookRetrieve类的方法a) BookRetrieve()是构造方法,用来创建成员变量,并注册监听器。b) itemStateChanged()是choice对象的事件处理方法。c) actionPerformed()是用来向服务器端发送图书查询请求,并接收服务器端的返回结果。类图:8)ManagerFrame类 该类是JFrame的子类并实现ActionListene
15、r接口 。用来实现交互界面的菜单栏。 A. ManagerFrame类的成员变量a) lbl-pic是用于显示图像的标签。b) menubar是窗口的菜单条。c) menu-book和menu-user是包含下级菜单项的菜单。d) mi-addbook、mi-delbook 、mi-viewbook 是menu-book菜单的下级菜单项。e) mi-adduser、mi-deluser 、mi-viewuser 是menu-user菜单的下级菜单项。B. ManagerFrame类的方法a) ManagerFrame()是构造方法,主要用来创建菜单条,菜单和菜单项,并注册动作监听器。b) ac
16、tionPerformed()是菜单项被电击后的事件处理方法。类图:9) add-book类 为JFrame的子类并实现ActionListener接口,实现用户添加图书时的界面需求。 A. add-book类的成员变量a) lbl-indexno等6个JLabel对象为显示提示信息的标签。b) txt-indexno等6个JTextField对象为提供信息输入的文本框。c) btn-ok和btn-cannel两个按钮,触发ActionPerformed方法的执行。B. add-book类的方法a) add-book()是构造方法,用来创建标签、文本框和按钮对象,并注册动作监听器。b) act
17、ionPerformed()是按钮被点击后的事件处理方法。类图:10)add-user类 为JFrame的子类并实现ActionListener和ItemListener接口,主要负责添加用户。 A. add-user类的成员变量a) lbl-uid等7个JLabel对象为显示提示信息的标签。b) txt-uid等4个JTextField对象为提供信息输入的文本框。c) rb-male、rb-female是对性别进行选择的单选按钮,而sex用于对这两者进行成组。d) cb-voca、cb-dept是分别提供对职业和部门进行选择的组合框。e) btn-ok和btn-cannel两个按钮,触发Ac
18、tionPerformed方法的执行。f) str-sex、str-voca、str-dept保存用户对于性别、职业和部门的选择信息。 B. add-user类的方法a) adduser()是构造方法,用来创建标签、文本框、单选钮、组合框和按钮对象,并注册动作监听器。b) actionPerformed()是按钮被点击后的事件处理方法。c) itemStateChanged()是单选钮和组合框中的选项改变时的事件处理方法。类图: 11)del-book类 为JFrame的子类并实现ActionListener接口,主要负责删除图书信息。A. del-book类的成员变量a) lbl-index
19、no是提示输入图书索引号的的标签。b) txt-indexno是用于输入图书索引号的文本框组件。c) btn-del是按钮,点击后触发actionEvent事件。B. del-book类的方法a) del-book是构造方法,用来初始化成员变量。b) actionPerformed()方法向服务器发出请求,并接受服务器端的返回结果。类图:12)view-user类 因为与BookRetrieve类的设计相似,此处省略类图:13)del-user类 因为与del-book类的设计相似,此处省略类图:各类间关系图:2、数据库的设计建立Access数据库“图书信息”,在其中建立数据表“图书信息表”、
20、“user” 等表,分别用于存放图书信息、用户信息等。 向表中录入适量数据,然后配置ODBC数据源“bookinfo”,与图书信息数据库建立关联,以便在程序中通过JDBC-ODBC桥来访问数据。4课程设计成果一、运行界面运行界面主要可以分为登录主界面、一般用户的图书查询界面以及管理员的工作窗口。1. 登录主界面可在一般用户和管理员间选择登录,在账号文本框中输入你的id,在密码文本框中输入你的密码,单击登录按钮即可登录到相应界面。2. 一般用户的图书查询界面用户可根据自身需要选择需要查询的选项,并填入相关信息,单击查询按钮就可实现对相应书籍的查询。3. 管理员的工作界面 管理员可以根据需要在菜单
21、中选择相应的功能加以实现,以达到增加、删除、查看图书和用户的目的。二、测试结果首先请原谅本人用于测试的相关数据之简少。Access数据库,即图书信息数据库中包含三张表,分别是图书信息表,user(一般用户信息表),manager(管理员信息表)。图书信息表:user:manager:利用以上数据测试程序是否正常运行,主要包括登录、查询、添加、删除图书以及用户是否正常(由于在运行界面中已经测试登录完全符合要求,以下省略)。查询图书:添加图书:如图,图书已经添加成功,我们可以看到相应的数据库表中也添加了相应记录:删除图书:如图,可根据图书的索引号删除相关书籍,当然这也是本系统的不足之处,即没有实现
22、按照其他关键字段进行删除的功能,日后定将改进。我们可以看到图书信息表中的相应记录已删除:查询用户:添加用户:如图,用户已经添加成功,我们可以看到相应的数据库表中也添加了相应记录:删除用户:如图,可根据用户的账号进行删除,当然这也是本系统的不足之处,即没有实现按照其他关键字段进行删除的功能,日后定将改进。我们可以看到user中的相应记录已删除:可以看到,本系统已基本实现所要求的各项的功能。此处附上服务器端和客户端的socket连接以及信息交互:服务器端:客户端:三、主要代码1) Server类:/工作于服务器端import java.io.*;import .*;/建立socket必须利用的包p
23、ublic class Server/服务器端主控类,创建ServerSocket对象,在端口监听请求创建Socket对象进行通信public static void main(String args)ServerSocket ss=null;Socket client=null;while(true)System.out.println(服务器等待连接.);tryss=new ServerSocket(8888);/创建ServerSocket对象,在端口监听来自客户端的连接请求 catch(IOException e)/异常处理 try client=ss.accept();/创建Sock
24、et对象,方便与客户端进行通信new ServerThread(client).start();/创建服务器端核心对象ServerThreadcatch(Exception e)System.out.println(客户端离开!); 2)ServerThread类/工作于服务器端import java.io.*;import .*;import java.sql.*;/操作数据库的包import java.util.*;/工具类和集合类public class ServerThread extends Thread/该类为服务器端的核心类,通过Server对象传递过来的Server对象值,借助
25、于DataInputStream对象和DataOutputStream对象提供的输入输出技术,根据客户端请求在服务器端进行相应的JDBC访问,并将处理结果返回Socket s=null;String str=null;DataInputStream in=null;DataOutputStream out=null;Connection con=null;ResultSet rs;public ServerThread(Socket s)this.s=s;tryif(s!=null)con=new GetConnection().getConnection();in=new DataInput
26、Stream(s.getInputStream();out=new DataOutputStream(s.getOutputStream();catch(IOException e) public void run()trystr=in.readUTF();/读取客户端的数据,str通过“:”进行分隔catch(IOException e1) /str的起始字符子串决定了客户端的请求类型if(str.startsWith(图书查询)/客户端发来的图书查询请求String choiceName=null,inputText=null;System.out.println(客户发来图书查询请求);
27、tryStringTokenizer fenxi=new StringTokenizer(str,:);if(fenxi.hasMoreTokens()String reqType=fenxi.nextToken();/取出请求类型System.out.println(reqType);if(fenxi.hasMoreTokens()/取出查询的字段名choiceName=fenxi.nextToken();System.out.println(choiceName);if(fenxi.hasMoreTokens()/取出查询的字段值inputText=fenxi.nextToken();Sy
28、stem.out.println(inputText);if(choiceName.equals(作者)/按作者字段查询PreparedStatement ps;ps=con.prepareStatement(select * from 图书信息表 where 作者 like ? order by 索引号);ps.setString(1,%+inputText+%);rs=ps.executeQuery();if(choiceName.equals(书名)/按书名字段查询PreparedStatement ps;ps=con.prepareStatement(select * from 图书信
29、息表 where 书名 like ? order by 索引号);ps.setString(1,%+inputText+%);rs=ps.executeQuery();if(choiceName.equals(出版社)/按出版社字段查询PreparedStatement ps;ps=con.prepareStatement(select * from 图书信息表 where 出版社 like ? order by 索引号);ps.setString(1,%+inputText+%);rs=ps.executeQuery();if(choiceName.equals(索引号)/按索引号字段查询P
30、reparedStatement ps;ps=con.prepareStatement(select * from 图书信息表 where 索引号=?);ps.setString(1,inputText);rs=ps.executeQuery();String backStr=;while(rs.next()/取出查询结果,保存到backStr中String author=rs.getString(1);String name=rs.getString(2);String publish=rs.getString(3);String publishTime=rs.getString(4);St
31、ring price=rs.getString(5);String indexno=rs.getString(6);backStr+=n作者:+author+;书名:+name+;出版社:+publish+;出版时间:+publishTime+;定价:+price+;索引号:+indexno;out.writeUTF(backStr);/将查询结果发回给客户端catch(Exception e) else if(str.startsWith(一般用户)/一般用户登录请求tryStringTokenizer fenxi=new StringTokenizer(str,:);int i=0,num
32、ber=fenxi.countTokens();String receiveStr=new Stringnumber;while(fenxi.hasMoreTokens()receiveStri=fenxi.nextToken();System.out.println(receiveStri);i+;PreparedStatement ps;ps=con.prepareStatement(select * from user where id=? and pwd=?);ps.setString(1,receiveStr1);ps.setString(2,receiveStr2);rs=ps.e
33、xecuteQuery();if(rs.next()out.writeUTF(登录成功);elseout.writeUTF(登录失败);catch(Exception e) else if(str.startsWith(管理员)/管理员登录请求tryStringTokenizer fenxi=new StringTokenizer(str,:);int i=0,number=fenxi.countTokens();String receiveStr=new Stringnumber;while(fenxi.hasMoreTokens()receiveStri=fenxi.nextToken()
34、;System.out.println(receiveStri);i+;PreparedStatement ps;ps=con.prepareStatement(select * from manager where id=? and pwd=?);ps.setString(1,receiveStr1);ps.setString(2,receiveStr2);rs=ps.executeQuery();if(rs.next()out.writeUTF(登录成功);elseout.writeUTF(登录失败);catch(Exception e) else if(str.startsWith(添加
35、图书)/客户端发来的添加图书请求System.out.println(客户端发来添加图书请求);tryStringTokenizer fenxi=new StringTokenizer(str,:);int i=0,number=fenxi.countTokens();String receiveStr=new Stringnumber;while(fenxi.hasMoreTokens()receiveStri=fenxi.nextToken();System.out.println(receiveStri);i+;PreparedStatement ps;ps=con.prepareSta
36、tement(insert into 图书信息表 values(?,?,?,?,?,?);ps.setString(1,receiveStr1);ps.setString(2,receiveStr2);ps.setString(3,receiveStr3);ps.setString(4,receiveStr4);ps.setString(5,receiveStr5);ps.setString(6,receiveStr6);int len=ps.executeUpdate();if(len=1)out.writeUTF(添加成功);elseout.writeUTF(添加失败);catch(Exc
37、eption e) else if(str.startsWith(添加一般用户)/客户端发来的添加用户请求 System.out.println(客户端发来添加用户请求);tryStringTokenizer fenxi=new StringTokenizer(str,:);int i=0,number=fenxi.countTokens();String receiveStr=new Stringnumber;while(fenxi.hasMoreTokens()receiveStri=fenxi.nextToken();System.out.println(receiveStri);i+;
38、PreparedStatement ps;ps=con.prepareStatement(insert into user values(?,?,?,?,?,?);ps.setString(1,receiveStr1);ps.setString(2,receiveStr2);ps.setString(3,receiveStr3);ps.setString(4,receiveStr4);ps.setString(5,receiveStr5);ps.setString(6,receiveStr6);int len=ps.executeUpdate();if(len=1)out.writeUTF(添
39、加成功);elseout.writeUTF(添加失败);catch(Exception e) else if(str.startsWith(删除图书)/客户端发来的删除图书请求 System.out.println(客户端发来删除图书请求);tryStringTokenizer fenxi=new StringTokenizer(str,:);int i=0,number=fenxi.countTokens();String receiveStr=new Stringnumber;while(fenxi.hasMoreTokens()receiveStri=fenxi.nextToken();
40、System.out.println(receiveStri);i+;PreparedStatement ps;ps=con.prepareStatement(delete * from 图书信息表 where 索引号=? );ps.setString(1,receiveStr1);int len=ps.executeUpdate();if(len=1)out.writeUTF(删除成功);elseout.writeUTF(删除失败);catch(Exception e) else if(str.startsWith(删除用户)/客户端发来的删除用户请求 System.out.println(客户端发来删除用户请求); try StringTokenizer fenxi=new StringTokenizer(str,:);int i=0,number=fenxi.countTokens();String receiveStr=new Stringnumber;while(fenxi.hasMoreTokens()receiveStri=fenxi.nextToken();System.out.