第一章 INTERNET 技术概述
1.1 计算机网络
1.1.1计算机网络的概念
计算机网络是利用通信线路连接起来的、相互独立的计算机的集合。这包含两个概念:首先,这些计算机之间必须存在通信线路;其次,这些计算机必须相互独立。从这个定义出发,传统的主机/终端式系统不能算是完全意义上的计算机网络。
按地理位置划分,计算机网络可以分为四种:网际网、广域网(WAN)、城域网(MAN)和局域网(LAN)。其中,INTENET就是世界上最大的广域网,另外还存在其他的网际网类型,它们通常连接着处于同一大洲或同一地域范围内的多个国家;广域网一般指连接一个国家的各个地区的网络,分布距离一般在100到1000公里之间;城域网又称都市网,它的覆盖范围一般为一个城市,方圆不过10到几十公里;局域网的地理分布则相对较小,例如一栋建筑物或一所学校。
计算机网络的传输速率通常以每秒传输的数据位来计算。从传输速度看,局域网的传输速率是最高的,城域网低于局域网,网际网的传输速率则相对较抵。
通信线路及连入网络的计算机结合在一起的整体布局模型称为网络拓扑。按网络拓扑划分,计算机网络可以分为总线网络、环网、星形网和混合网络等。 连入网络的各计算机称为主机(HOST)或节点(NODE)。
1.1.2网络协议
计算机网络利用利用通信线路连接起来,网络用户在计算机之间通过网络交换信息。就如人与人之间相互交流时需要遵循一定的规矩一样,计算机之间的相互通信也要共同遵守一定的规则,这些规则称为计算机网络协议。
网络协议通常分为几个层次,每层完成自己的功能。通信双方只有在相同层之间才需要相互联系。低层协议为高层协议提供服务。
开放系统互连参考模型(OSI)是国际标准化组织(ISO)推出的网络互连的标准模型。整个模型分为7层,如图(1-1)所示。
应 用 层
对 话 层
传 输 层
数 据 链 路 层
网 络 层
表 示 层
物 理 层 图 1-1
l TCP/IP协议
OSI分层协议模型更多的是被作为一个理论模型,与此模型相对应,一个非常实用的网络协议是TCP/IP协议。
TCP/IP这个名称可以分为两部分:TCP 和 IP 。TCP其实是“传输控制协议“(TRANSPORT CONTROL PROTOCOL)的缩写,IP 表示”INTETNET协议“或称IP协议(INTERNET PROTOCOL)。不过,TCP/IP 却不仅仅代表这两个协议,它表示的是协议的集合,称为TCP/IP 协议簇(PROTOCOL SUITE)。一个协议集就是指由一系列相互补充且互相协作的协议所构成的集合。除传输控制协议和IP协议外,TCP/IP 还包括其他一些协议。下表(1-1)给出了一些常用的TCP/IP 协议。
协议
用 途
IP
用于在主机之间传送数据
TCP
用于在程序之间传送数据
UDP
用户数据报协议
ICMP
INTERNET控制报文协议
表 1-1
除了上面的4个协议外,TCP/IP 协议集还包括了其他一些协议,其中最重要的包括:(表1-2):
TCP/IP 协议分为以下4层:
网络接口层:负责接收和发送物理祯;
网络层: 负责相邻节点之间的通信;
传输层: 负责起点到终点的通信;
应用层: 提供诸如文件传输、电子邮件等应用程序。
协议
全名称
UUCP
Unix-Unix Copy Protocol
简单网络管理协议(SNMP)
Simple Network Managerment Protocol
简单邮件传输协议(SMTP)
Simple Mail Transmission Protocol
网络新闻传送协议(NNTP)
NetNews Transfer Protocol
文件传输协议 (FTP)
File Transfer Protocol
点对点通信协议 (PPP)
Point to Point Protocol
串行线路IP协议(SLIP)
Serial Line Internet Protocol
超文本传输协议(HTTP)
Hyper Text Transport Protocol
表1-2
l HTTP协议---超文本传输协议
HTTP协议将在以后的章节中重点讲述。
1.1.3 INTERNET 的服务与应用
尽管电子邮件(EMAIL)是最常用、最为重要的INTERNET应用,但它远非唯一的INTERNET 服务。目前人们常用的INTERNET服务包括文件传输服务(FTP)、远程登陆服务(TELNET)、网络新闻、以及各种查询服务,如GOPHER、 WAIS 和WWW 等。新的INTERNET 服务也层出不穷。
1.2 World Wide Web
1.2.1 WWW的概述
WWW(World Wide Web,国内称之为万维网, 环球网)是目前INTERNET上最快炙人口的信息服务类型,它的影响力已经进入了广告、新闻、销售、服务等各个行业,是世界上最大的电子信息仓库。
WWW问世之初并未引起太多的重视,它的广泛应用始于MOSAIC的问世。1993年初,NCSA的MARC ANDRESSEN 成功地推出了MOSAIC的最初版本。作为一个设计新颖、使用方便的www浏览器软件,Mosaic 立即引起了世人的注意,并几乎成了WWW的代名词。在MOSAIC之后,新的浏览器软件层出不穷,促使了WWW的迅速发展。
WWW最初是由欧洲粒子物理实验室CERN(EUROPEAN PARTICLE PHYSICS LAB)的TIMBERNERS-LEE于1989年负责开发的。TIMEBERNERS-LEE设计的实际上是HTML语言,其目的在于为分散在世界各地的物理学家组成的合作工作组提供信息服务,使组内的成员可以方便的交换信息,或交换彼此的想法。
我们可以给WWW下一个非正式的定义:WWW是建立在客户机/服务器模型之上,以HTML语言和HTTP协议为基础,能够提供面向各种INTERNET 服务的一致的用户界面的消息浏览系统。其中WWW服务器利用超文本链路来链接各种信息片段,这些信息片段即可以放置在同一主机上,也可放在不同地理位置的不同主机上;超文本链路由统一资源定位器(URL)维持;WWW客户(也就是我们常说的WWW浏览器)则负责如何显示信息和向服务器发送请求。
WWW是以INTERNET 作为传输媒介的一个应用系统。 INTERNET不是一个单一的网络,而是把全球范围内的网络连接在一起而形成的全球网。WWW上最基本的传输单位是WEB网页。一个网页中可以包含文字、图形、声音和视频剪辑。除此之外,网页中还包含一种称为超级链接的特殊正文。WEB与传统的INTERNET服务GOPHER,WAIS 等的最大区别是它展示给用户的是一篇篇的文章,而不是令人费解的菜单说明。因此,用它查询消息有很强的直观性。用户可以通过浏览器访问WEB站点,从而浏览文本和图形,接收视频和音频信息(即所谓的超媒体)。WWW服务器使用的主要协议是HTTP协议,即超文本传输协议。基于http协议的服务器不限于WWW,还可以是其它形式的信息。因而HTTP允许用户在一个统一界面下,可以采用不同的协议访问不同的服务,如FTP, SMTP等。
WWW服务系统主要由两部分组成,采用的是客户/服务器模式,位于服务器一端的WWW服务器和位于用户一端的HTML文档的浏览器,浏览器是连到WWW服务器的客户机。WWW服务器的任务就是等待客户机的连接,及时响应客户机的请求,并给出相应的回答。WWW主要采用HTTP协议,并使用URL、HTML和CGI进行信息的定位、存取和显示,通过一个浏览器可以访问多个应用服务器,形成点到多点、多点到多点的结构模式。
WWW服务器由WWW客户机(WWW浏览器)和WWW服务器组成,基于客户机/服务器的解决方案。通过TCP/IP网络,WWW 浏览器首先与WWW服务器建立连接,浏览器发送客户请求,WWW服务器作出相应的响应,回答响应数据,最后关闭连接。一次基于HTTP协议的会话完成。
基本步骤如下:
1. WEB浏览器向某个特定的WEB服务器发出需要某个网页的请求;
2. WEB服务器收到需要网页的请求,在文档空间搜索特定的网页,并 把此网页发送给WEB浏览器;
3. WEB浏览器收到并显示WEB网页的内容。
1.2.2 Web的三个发展阶段
1.静态简单网页,网页主要局限于文字信息,并且客户只能浏览到服务器系统管理员编写好的超文本文件,信息量受限制。
2.图文并貌网页,网页上不仅可浏览到文字,还可以浏览到精美的 图象甚至声音文件。网页上可以进行简单查询和网页访问计数等功能。
3.动态网页,利用Web机制使后台数据库与WEB服务器结合,靠后台数据库提供实时数据更新和数据查询服务,此阶段正在发展完善之中。
此次,我所要完成的毕业设计,所涉及的内容主要也包括用一种新的技术JAVA APPLET来实现动态的网页。
第二章
WWW的主要协议—HTTP协议
Internet的基本协议是TCP/IP协议,目前广泛采用的FTP、 Archie、Gopher协议是TCP/IP应用层协议,不同的协议对应着不同的应用。
而WWW服务器使用的主要协议是HTTP协议,即超文本传输协议。 HTTP协议位于OSI模型的应用层,基于http协议的服务器不限于WWW,还可以是其它形式的信息。因而HTTP允许用户在一个统一界面下,可以采用不同的协议访问不同的服务,如FTP, SMTP等。
HTTP是为分布式超媒体信息系统设计的一个协议,它是无状态、面向对象的协议。HTTP还可用于名字服务器和分布式对象管理。
HTTP协议于1990年提出,经过几年的使用与发展,HTTP得以不断地完善和扩展。目前在WWW中使用的是HTTP/1.0,和HTTP/1.1。HTTPNG(Next Generation of HTTP)的建议已经提出。
一、HTTP协议的主要特点:
1)支持客户/服务器模式;
2)简单快速
客户机向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的不同类型。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。
3)灵活
HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标价。
4)无连接
无连接的含义是限制每次连接只处理一个请求。服务器处理完客户机的请求,并收到客户机的应答后,即断开连接。采用这种方式可以节省传输时间的占用。
5)无状态
HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着后续处理所需的前面信息必须重视,这样导致每次连接要传送的数据量增大。然而,另一方面,服务器也因此应答较快。
6)元信息
HTTP对所有事务处理都加了头,在主要数据前加上一块信息(元信息,即信息的信息),它使服务器能够提供正在传送数据的有关信息。
二、HTTP协议的作用原理
在WWW中,"客户机"与"服务器"是一个相对的概念,只存在于一个特定的连接期间,即在某个连接中的客户机在另一个连接中可能作为服务器。服务器运行时,一直在TCP80端口(WWW的缺省端口)监听,等待连接的出现。HTTP协议的作用原理包括四个步骤:
1.连接
WEB浏览器与WEB服务器建立连接,打开一个称为套接字(Socket)的虚拟文件,并把它约束在一个端口上。打开一个套接字就是建立一个虚拟文件,此文件的建立标志着连接建立成功。
2.请求
打开一个连接后,WEB浏览器通过SOCKET向WEB服务器提交请求。
HTTP的请求一般是GET 或POST命令。
HTTP/1.0 请求消息的格式为:
请求消息=请求行(通用信息|请求头|实体头)CRLF[实体内容]
请求行=方法 请求URL HTTP版本号CRLF
方法=GET|HEAD|POST|扩展方法
URL=协议名称+宿主名+目录与文件名
请求行中的方法描述为在指定资源中应该执行的动作,常用的方法有GET、HEAD和POST。
不同的请求对象对应的GET的结果是不同的,对应关系如下:
对象 GET的结果
文件 文件的内容
程序 该程序的执行结果
数据库查询 查询结果
HEAD———要求服务器查找某对象的元信息,而不是对象本身
POST———从客户机向服务器传送数据,要求服务器和CGI做进一步处理时会用到POST方法。POST主要用于发送HTML FORM的内容,让CGI程序处理。
一个请求的例子为:
GET http://WWW.swjtu.edu.cn/home.html HTTP/1.0
头信息又称为元信息,即信息的信息,利用元信息可以实现有条件的请求或应答。
请求头———告诉服务器怎样解释本次请求,主要包括用户可以接受的数据类型、压缩方法和语言等。
实体头———实体信息类型、长度、压缩方法,最后一次修改时间、数据有效期等。
实体———请求或应答对象本身。
3.应答
WEB服务器在处理完客户的请求之后,要通过HTTP向WEB客户机发送处理结果。HTTP/1.0的响应消息格式如下:
响应消息=状态行(通用信息头|响应头|实体头)CRLF[实体内容]
状态行=HTTP版本号 状态码原因叙述
状态码表示响应类型
1×× 保留
2×× 表示请求成功地接收
3×× 为完成请求客户需进一步细化请求
4×× 客户错误
5×× 服务器错误
为了告之WEB浏览器传送内容的类型,WEB服务器首先传送一些HTTP头信息,然后传送具体内容(即HTTP体信息),HTTP头信息和HTTP体信息之间用一个空行分开。
4)关闭连接
当服务结束后,WEB浏览器与WEB服务器必须断开,以保证其他的WEB浏览器能够与WEB服务器建立连接。
第三章JAVA语言
3.1 JAVA语言的介绍
3.1.1 JAVA语言出现的背景
目前,计算机界最热门的就是INTERNET了 ,而当前INTERNET上最吸引人的就是JAVA。JAVA语言以其强大的生命力吸引着软件开发者,而INTERNET 上蕴藏了JAVA语言各种模式的无尽的信息资源。
WWW(WORLD WIDE WEB)正在成为世界上最大的信息中心。但WWW上大多为文本、图形、声音等静态信息,JAVA 为其提供了极为简单且功能强大的编程接口,向开发人员提供了向WEB增加动态,交互性内容的功能,使得WEB页面又翻开了新的一页。
JAVA是一种面向对象的语言,允许开发人员生成独立于平台的应用程序。因为JAVA是一种解释性语言,所以用它编写的程序可以在许多的硬件平台运行而无须重新编译。它同时还是一个功能强大的安全模块,可以让你生成用户可以下载的APPLET 而无须担心在你的计算机上发生任何不安全的事情。
JAVA的基本解释器只有40K左右,加上标准类库和线程的支持也不过215K左右,可谓短小精悍,而功能毫不逊色,对多线程到面向对象以至于多媒体都全面支持。
另外,传统的编程软件往往依赖于具体实现环境,一旦更换则可能有大批已有代码需要重新编写或重新编译。JAVA在二进制代码上的兼容性使得同一软件能不加修改的用于不同系统之上,只需要提供相应的JAVA解释器即可。因此,JAVA程序可以非常简单地移植到网络上的不同的机器上,而只有这样的程序设计语言才能满足网络上的形形色色的系统的不同的要求。因此,有人预言:JAVA将是网络上的“世界语”。
3.1.2 JAVA的特点
一.简单性
JAVA的简单性首先体现在精简的系统,力图用最小的系统实现足够多的功能。无需强大的硬件环境,JAVA在小型的机器上便可以良好的运行。
JAVA语言基于C++,但它除去了C++中许多的难得一用的而又复杂不易理解的部分,并去掉了将潜在地威胁JAVA安全的模块。所保留的只是一个简单的、面向对象的多线程语言,其特性包括一个单继承的类系,强类型,支持多线程执行,自动碎片收集,并且只采用引用。
JAVA 实现了自动的垃圾收集,程序的设计者不必费心地管理内存,一切工作由系统完成。这不但使程序设计更加简单,同时也大大减少了出错的可能。
二.面向对象技术
和所有的新一代的程序设计语言一样,JAVA也采用了面向对象技术并更加彻底,所有的JAVA程序和APPLET均是对象,封装性实现了模块化和信息隐藏,继承性实现了代码的复用,使用户可以建立自己的类库。
三.分布性
通过JAVA提供的类库可以方便地处理TCP/IP协议,用户的应用程序可以通过URL地址访问网络上的其他对象,就象访问本地文件一样简单。
四.鲁棒性
JAVA在编译及运行程序时,都要进行严格的检查,以消除错误发生的可能。作为一种强类型语言,JAVA在编译和连接时进行大量的检查,防止不匹配的错误发生。在JAVA程序中不能采用地址计算的方法通过指针访问内存单元,这样就大大减少了错误发生的可能性,JAVA的数组并非用指针实现,这样可以在检查中避免数组越界的发生。JAVA的自动垃圾收集避免了管理内存时容易出现的许多错误。
五.安全性
网络上最重要的是安全问题,作为网络语言,JAVA必须提供足够的安全保证,并且要防止病毒的入侵。JAVA在运行应用程序时,严格检查其访问数据的权限,例如不允许网络上的应用程序修改本地的数据。下载到用户计算机中的字节代码在其被执行前要经过核实,之后,由JAVA运行时解释器来执行,该解释器通过阻止对内存的直接访问来进一步提高JAVA的安全性。
六.体系结构中立
为使JAVA程序能在网络的任何地方运行,JAVA解释器生成与体系结构无关的字节码结构的文件格式,他们能在任何种类的处理器上运行,只需提供相应的JAVA运行系统.这样,实现了一次编写到处运行。
七.可移植性
体系结构中立使得JAVA程序具有可移植性。同时JAVA的类库也具有可移植性,可以在不同的平台上使用。另外,JAVA的编译器由JAVA语言实现,运行器由标准C实现,因此JAVA本身也具有可移植性。
八.可解释执行
JAVA解释器直接对JAVA字节码解释执行,字节码本身包含了许多编译时产生的信息,使连接过程变的更加简单。
九. 多线程
多线程使应用程序可以同时进行不同的操作,处理不同的事件。网络连接需要时间,如果采用事件循环机制则会造成长时间的等待。在多线程机制中,不同的线程处理不同的任务,他们之间互不干涉,这样可以容易地实现网络上的实时交互操作。
十.动态性
在许多方面,JAVA比C,C++更具有动态性,它被设计为适用于不断发展的环境。在类库中可以自由地加入新的方法或变量,而不会影响使用这一类库的应用程序的执行。
3.1.3 JAVA的SOCKET通信
JAVA语言本身具备了独具特色的网络优势与网络功能。
JAVA的SOCKET通信提供了一种可靠的基于连接的通信机制,所谓SOCKET可以设想成是两个不同的程序通过网络的通信管道,这也是网络程序最常用的方式。为了利用SOCKET通信,必须先打开通讯连接,其实质上就是建立一个新的SOCKET实例:Socket object_socket = new Socket(hostname,portnum)。JAVA的所有的输入/输出操作都是采用流来实现的。在建立SOCKET连接后,可以用SOCKET对象的getInputStream()和getOutputStream()方法分别取得其输入流和输出流,对输入流再用DataInputStream流进行过滤处理,对输出流则常用PrintStream 流或DataOutputStream 流过滤,进而可用更高级的方法进行数据的读写,如DataInputStream流的readLine() 方法可以从流中读取一行字符串,PrintStream流的Println() 方法可以往流中写入一行字符串。
JAVA为我们提供了客户端的SOCKET类和服务器端的SERVERSOCKET类,它们的工作方式类似,在使用同一个端口号(PORTMUN)建立连接后,就可以使用以上提供的方法进行通信了。在SERVERSOCKET类中,我们使用accept( )方法从客户端接收连接。
无论一个SOCKET通信的功能多么齐全,程序多么复杂,其基本结构都是一样的,都包括以下四个基本的步骤:
1. 打开SOCKET;
2. 打开连接到SOCKET的输入/输出流;
3. 按照一定的协议对SOCKET进行读/写操作;
4. 关闭SOCKET。
通常,程序员主要是针对所要完成的功能在第3步进行编程,第1、2、4步对任何程序几乎都是一样的。
3.2 JDBC
JAVA 语言所具有的鲁棒性、安全性、可移植性,容易理解,方便使用并且可以自动下载等优点,使得它成为发展数据库应用的极好的语言基础,它较之C++、SMALLTALK、COBAL等语言有很多的优势,并提供了更大的应用范围和应用的多样化。
1996年2月20日,JavaSoft 公司宣布了JDBC API ,这是一个标准SQL数据库访问接口, 它给JAVA设计人员提供了与多种关系数据库的统一接口。和JAVA语言一样,JDBC 也是独立与平台和数据库的,为了在平台上运行JDBC,JAVA虚拟机应有本地驱动器管理器,对特定的数据库,则需要数据库驱动程序。迄今为止,JDBC得到了广泛支持, 许多厂商如IBM、ORACLE 、Sysbase、Informix、Borland、SCO等公司都声名支持JDBC,其逐渐成为WEB服务器访问数据库的接口的事实标准.
一个独立于特定的数据库管理系统(DBMS-INDEPENDENT)的用户界面是实现DBMS应用的广泛性和多样化的最快的方式。JAVA语言应用程序的开发者们正是基于此观点,提出了一个通用的一般的SQL数据库访问和存储结构,这就是JDBC(JAVA DATABASE CONNECTIVITY),JDBC 是支持基本SQL功能的一个通用低层的应用程序编程接口(API),它在不同的数据库功能模块的层次上提供了一个统一的用户界面。这使得程序员只要面对简单的数据库界面进行操作,使得独立于DBMS 的JAVA应用程序的开发工具和产品成为可能,同时也提供了多样化的数据库连接方式。
JDBC是建立在X/OPEN SQL CLI(CALL LEVEL INTERFACE)基础之上的,它定义了一个友好的JAVA界面来与X/OPEN SQL CLI中定义的基本抽象层和基本概念来进行连接。ODBC不适和在JAVA中直接使用,因为它使用 C语言界面.从JAVA中直接调用本地的 C代码有许多不利之处:安全,执行,鲁棒,及应用程序的精悍。从ODBC C API直译进入JAVA API也是不可取的.例如,JAVA没有指针,但 ODBC对指针有丰富的应用,你可以考虑把JDBC作为 ODBC转换成面向对象的界面。
JDBC提供了一个标准的 API工具给数据库开发者,使之有可能用纯的JAVA API编写数据库应用程序。用 JDBC,可以很容易地传送 SQL语句给事实上的任何关系数据库。换句话说,用 JDBC API,不需要编写一个程序来访问 Sybase数据库,写另一个程序来访问ORACLE数据库,再用另一个程序来访问 Informix数据库,等等。你可以用 JDBC API仅仅写一个程序,此程序将能把 SQL语句送给适当的数据库.并且,用JAVA API 编写应用程序,一也不必担心要为不同平台编写不同应用程序。JAVA和 JDBC的组合让程序员一旦编写好一个应用程序就可以到处运行。JAVA,是鲁棒的,安全,容易使用,容易了解的,并且可自动下载在网络运行,是杰出的基于数据库应用的语言。
JDBC的特点
1.在SQL 水平上的API
JDBC是为JAVA语言定义的一个SQL调用级(CLI)界面,也就是说其中心在于执行基本的SQL声明和取回结果。在此基础上可以定义更高层次的API ,其中的接口包括直接将基本表与JAVA中的类相对应,提供更多的通用查询的语义树表示,以及JAVA的嵌入式SQL语法等。
2.与SQL的一致性
一般数据库系统在很大的范围内支持SQL的语义语法,但他们所支持的一般只是SQL语法全集中的一个子集,并且他们在许多更强的功能例如外部连接及过程存储等方面彼此不能一致,而现在的标准SQL扩展能包含更多的功能,JDBC是通过以下几方面来保证与SQL的一致性:
1)JDBC允许使用从属于DBMS的系统的任何查询语句,因此一个应用程序可以使用尽可能的SQL功能。也就是说不限制用户使用所有的SQL语法,而是通过驱动程序来加以限制,用户可以通过使用JDBC中提供的一些功能函数来获取有关数据库的基本信息,再对数据库进行操作来避免错误。实际上,一个应用程序的查询基本不必是SQL形成的,它可以是SQL的特定演化形式,例如为特定DBMS而提供的文本或是图象查询等。
2)一般认为ANSI SQL 92 Entry Level 标准功能比较完备,并且是被广泛支持的,所以为了使JDBC与SQL一致,要求用户使用至少ANSI SQL 92 Entry Level以上标准,这样就给那些要求广泛的可携带性的应用程序提供了至少共同命名的保证。
3 .可在现有数据库接口之上实现
JDBC SQL API保证能在普通的SQL API上实现,特别是ODBC。这使JDBC的功能变得更加丰富,尤其是在处理OUT参数及大的数据块的处理上。
4.提供与其他Java系统一致的Java界面
JDBC提供与Java系统其他部分一致的Java界面,这对于Java语言来说有着非常重要而且积极的意义。在很大程度上这意味着Java语言与标准运行系统被认为是一致的、简单化的并且是功能强大的。
5. 简单易行
JDBC的基本API在最大可能上简单化,这也体现在大多数情况下采用简单的结构来实现特定的任务而不是提供复杂的结构,或者说对某个特定的任务,只提供一种方案,而不是多种复杂的方案。JDBC的API以后还将不断扩展以实现更完善的功能。
6. 使用健壮,静态的通用数据类型
JDBC API使用健壮的数据类型,并且很多类型信息采用静态表达,这就使得很多的错误在编译时被捕获。但是,由于SQL本身是动态数据类型,所以在程序运行时,就有可能会碰到类型不匹配的问题,例如在对所操作的数据库基本信息未知的情况下,就可能发生程序员希望一个SELECT语句返回整数结果,而数据库返回的是字符串类型的情况。这时,程序员可以在操作前使用API中定义的一些基本方法,来对数据库的数据类型进行查询,这样程序员在编译时提出他们所期望的数据类型,就能尽可能的进行静态查询,在需要时,也支持动态数据类型的界面。
7. 使一般情形简单化
JDBC使得一般任务简单化,而不是一般的任务成为可执行的。
所谓一般任务指的是程序员执行一个简单的没有参数的SQL声明(如SELECT、INSERT、UPDATE或DELETE),然后获得简单的结果集,带有传入参数IN的SQL声明也属于一般情形。
另外一些情况不是那么常见,但仍然很重要,这就是当程序员使用带INOUT或OUT的参数的SQL声明以及支持读写多兆字节大数据块的SQL声明等,更特殊的情形如一个SQL声明返回多个结果集合。
8. 多种方法,多种功能
ODBC中定义的界面类型采用的是一种方法,多种功能的方法,即使用少量的过程,而提供大量的控制标志作为过程的传递参数,这样就可以用它们来对不同的操作提供更为广阔的范围。而Java的核心的类都使用不同方法来完成相似的功能,在JDBC中也采用了这种思想,也就是用多种方法而不是带有标志项的多目的的方法。这使得我们学习基本接口时不必与复杂功能相关的参数所困扰。
JDBC的两种主要接口
JDBC主要有两种接口,分别是面向程序开发人员的JDBC API和面向
图3.1
底层的JDBC Drive API,它们的功能如图(3-1)所示:
JDBC API是一系列抽象的接口,它使得应用程序员能够进行数据库连接,执行SQL声明,并且得到返回结果。
图中所示为一些最重要的接口,他们是:
java.sql.Drive Manager 用来处理装载驱动程序并且为创建新的数据库连接提供支持;
java.sql.Connection完成对某一指定数据库连接功能;
java.sql.Statement 在一个给定的连接中作为SQL执行声明的容器,它包含了两个重要的子类型;
java.sql.PreparedStatement 用于执行预编译的SQL声明;
java.sql.CallableStatement 用于执行数据库中存储过程的调用;
java.sql.ResultSet 控制对于给定声明取得结果列的途径。
图(3-2)反映了各个接口之间的关系:
图3-2
JDBC Driver Interface
JDBC DRIVER API 面向驱动程序开发商的编程接口,对于大多数的数据库驱动程序来说,仅仅实现JDBC API 提供的抽象的类就可以了。即每一个驱动程序都必须提供对于java.sql.* 的主要接口的实现方法。
另外,当java.sql.DriveManager 需要为一个特定的数据库URL装载驱动程序时,每个驱动程序就需要提供一个能实现java.sql.Driver 接口的类。
JAVASOFT 公司提出了在ODBC 的基础上实现JDBC的方法,也就是JDBC-ODBC Bridge,因为JDBC在某种程度上套用了ODBC ,所以这种实现就很方便并且效率很高。
第四章 课题分析
4.1 课题的具体要求
此次毕业设计的题目是:数据库综合查询,其具体要求有以下几条:
1. WEB查询,也就是用户可以通过浏览器对数据库中的信息进行查询
2. 动态的网页技术,与用户进行交互,方便使用,图文并茂
3. 通过ODBC来实现与多种数据库的连接,而不用专用的单一数据库驱动程序
4. 跨平台性,这是更高一步的要求
4.2 具体分析与方案的选择经过
4.2.1 两种结构体系的比较
WEB与数据库的集成技术及WEB服务器与数据库的连接技术是此次设计的核心,这两者的方案不止一种,如何从中选取一种以符合以上的要求,并实现高效、稳定的运行是极为关键的。
WEB模型是一种从传统的CLIENT/SERVER模型发展起来的新的计算模式。称为BROWSER/SERVER(浏览器/服务器)模型。其本质是三层结构C/S。而C/S是松散耦合系统,它们通过消息传递机制进行对话,由客户端发出请求给服务器,服务器进行相应的处理后经传递机制送回客户端,其模型可见图(4-1)。尽管C/S模型是成功的,但它存在着明显的不足:
1.它大大加重了客户端的负担,降低运行性能;
2.受到数据库厂家所提供库的限制,从一个厂家的数据库向另一个厂家的数据库转变时,需要改写大量的客户机程序代码;
3.客户直接对后端数据库进行操作,不宜进行集中管理,存在缺乏安全型问题;
4.当发布客户端应用时,需要对客户机进行烦琐的配置,若客户机应用需要升级,则需要重新编译,再发布。
而BROWSER/SERVER则把C/S模型的服务器端进一步深化,分解成一个应用服务器(WEB服务器)和一个或多个数据库服务器,从而
图 4-1 C/S 模型
成为三层C/S模型,如图(4-2)所示。
在C/S模型中,所有的客户端需要配置好几层软件,如操作系统、网络协议软件、客户机软件、开发工具及应用程序等,而在服务器端则是单纯的数据库服务器。BROWSER/SERVER模型则简化了C/S的客户端,只需安装操作系统、网络协议软件和浏览器即可,而服务器端则集中了所有的应用逻辑,开发、维护等几乎所有的工作也都集中在服务器端。浏览器从网络上下载应用,WEB的应用服务器将信息组织成分布式的超文本,通过超文本标记语言(HTML)来描述和组织信息。简单和实用地实现了以整个INTERNET网络为背景的数据库应用系统。
浏览器(BROWSER)
网络软件,操作系统 客户机子系统
HTTP协议 网络子系统
HTML文件系统
CGI
SCRIPT
WEB开发
工具
应用
WWW WEB SERVER
网络操作系统
数据库服务器
服务器子系统
图4-2 三层结构框架图
三层结构带来的好处:
1. 提高了性能和可伸缩性。客户直接连接后台的服务器,因后台服务器上可能存在多种数据库管理系统,使前台的连接与培植复杂化。中间层的设定,使客户机能瘦下来,又不完全增加后台数据库管理系统的负担。使任一客户机、中间层、后台服务器形成了如图(4-2)的结构
2. 可以根据整个系统的负载情况,增减中间层与后台服务器的数量,这样就大幅度提高了系统的性能和可伸缩性。
3. 提高了可靠性。多个WEB SERVER 分布在多个机器上避免了单点失败,连接的失败服务器对象上的客户可以被透明地重新连接到正常运行的服务对象上,从而提高了关键应用的可靠性。
4. 提高了可管理性。对瘦客户机的安装和培植也相应变的简单,在浏览器中一行的程序也不需编写,下载后就可以使用,而使管理都集中在WEB SERVER 和后台服务器上。
5. 提高了灵活性和开发效率。综合查询的应用程序都存放在WEB SERVER 上,不必为每个平台开发专门的客户机程序。服务器对象可以根据事物处理规则的变化很快作出修改,不用对客户端做变化。
4.2.2 几种接口技术的比较
WEB与数据库的集成并不是新的技术,早在WEB诞生的初期,就可以利用通用网关接口(CGI)动态地访问企业数据库。随着应用普及,WEB服务器与数据库服务器的连接显得越来越重要,许多厂商不断地推出新的接口技术,使的这种连接更加简洁、方便和高效。
现在我们来比较一下几种目前广泛应用的接口技术的各自的特点,以阐述我的方案的优势所在。
1. 通用网关接口技术(CGI)
WEB浏览器输入的协同工作数据,完成客户端与服务器的交互工作,扩展服务器的功能,完成服务器本身不能完成的工作。外部程序执行时可以生成HTML文挡,并将文档返回WEB服务器。
CGI应用程序能够与浏览器进行交互作用;还可以通过数据库的API与数据库服务器等外部数据源进行通信。如一个CGI程序可以从数据库服务器中获得数据,然后格式化为HTML文档后发送给浏览器,也可以从浏览器获得数据放到数据库中。这样,客户端的用户就可以用WEB服务器进行数据处理。几乎所有的服务器软件都支持CGI,开发者可以使用任一种WEB服务器内置语言编写CGI语句,其中包括广围流行的PERL语言、C、C++ 、VB、DELPHI等。
按照数据通信方式的不同,CGI可以分为标准CGI和缓冲CGI。所有的WEB服务器均支持标准CGI,按标准CGI编写的程序与具体的WEB服务器无关。而按缓冲CGI编写的程序与具体的WEB服务器有关。
标准CGI
标准CGI使用命令行参数或环境变量来表示服务器的请求信息,服务器与浏览器间的数据通信采用标准I/O方式。如图(4-3)所示
当客户端的用户完成了输入后,向WEB服务器发出HTTP请求(即CGI请求),服务器守护进程接到该请求后,对该请求进行分析,设置所需的命令行参数或环境变量,然后创建一个子进程启动RUL指定的CGI程序,在外部CGI程序与服务器间I/O通道,并与该子进程保持同步,以监测CGI程序的运行状态。。子进程通过标准输出将执行结果返回给服务器守护进程,守护进程再将处理结果作为应答消息回到客户端。CGI可以输出很多类型,如HTML文档、图象、纯文本或声音等。
数据库服务器 环境变量
WEB客户端
(浏览器) 命令行参数
。。。。 标准输入
标准输出
图4-3
缓冲CGI
缓冲CGI 也称为间接CGI或WIN CGI 。此时,CGI扩展程序与服务器间通过缓冲CGI(称为缓冲区)而不是标准的CGI接口进行通信,但缓冲CGI与服务器间的通信还是通过标准CGI接口,由WEB服务器的内置缓冲处理程序实现。
虽然CGI大大扩充了Web 的应用范围,但这种技术也存在以下不足:
1. 缺乏平台无关性。CGI 是用c,Perl,Shell 等语言编写,所以无法作到一次编写到处运行,这无形中将增加以后的投入;
2. 运行性能交差。 当它每次接收到用户的请求时,将产生一个新进程,通常启动时间较长,但当处理完请求时,却不在内存中保留这个进程,所以,当接受到一个新的请求时,仍将化很长的时间用于启动,哪怕是同一个请求。在多用户环境中,这显然会给服务器增加很大的负担,降低运行性能。
另外还有安全性和CGI 之间通讯差的问题,而采用用JAVA构造的小服务器却可以克服这些缺点。
2.WEB服务器应用编程接口(API)
有些WEB服务器软件厂商针对CGI运行效率低下、编程困难等缺点,开发了各自的服务器API(APPLICATION PROGRAMMING INTERFACE),试图克服CGI性能方面的缺陷。
MICROSOFT 的IDC
IDC模块是IIS的一个动态连接库(DLL),它通过ODBC(开放数据库连接)访问各类数据库,它使得WEB页面中包含由数据库信息。可以由用户在页面上输入信息来插入、修改和删除数据库中的信息,允许由SQL命令来操作数据库。图(4-4)是通过IDC访问数据库的示意图,这是WEB服务器端的结果,其中的HTTPODBC.DLL就是IDC模块。
IDC 使用了两类文件:IDC脚本文件(.IDC)和HTML模板文件(.HTX)。
IDC的工作原理是:当WEB服务器IIS对由浏览器送过来的RUL字符串作出反应时,如果该字符串以 .IDC结束,IIS 就知道这是个IDC请求,将其传给IDC模块,IDC依次读取脚本文件并同数据库服务器交互.IDC模块从数据库得到结果后,就用模板文件( .HTX)格式化结果,得到一个时际的HTML文档,然后将该文档传送给WEB服务器IIS,由IIS负责将HTML文档返回给浏览器。
WEB客户端(浏览器)
HTTP HTML
WEB服务器
.HTX
ISAPI接口
HTTPODBC。DLL
.IDC SQL返回数据
SQL请求
ODBC
SQL服务器驱动程序
数据库服务器(DBMS)
数据库
数据库
图4-4
3.JAVA数据库互连接口(JDBC)
JAVA的推出,使WEB页面有了活力和动感。用户可以从WEB服务器上下载JAVA小应用程序到本地浏览器上运行。这些下载 的小程序可以象本地程序一样,独立地访问本地和其他服务器的资源。
JDBC的原理
JDBC是一种可用于执行SQL语句的数据库API,它由一些JAVA语言写的类,界面组成。它在功能上与ODBC相同,给开发人员提供了一个统一的、标准的数据库访问接口。JDBC提供了一个标准的 API工具给数据库开发者,使之有可能用纯的JAVA API编写数据库应用程序。用 JDBC,可以很容易地传送 SQL语句给事实上的任何关系数据库。换句话说,用 JDBC API,不需要编写一个程序来访问 Sybase数据库,写另一个程序来访问ORACLE数据库,再用另一个程序来访问 Informix数据库,等等.你可以用 JDBC API仅仅写一个程序,此程序将能把 SQL语句送给适当的数据库.并且,用JAVA API 编写应用程序,一也不必担心要为不同平台编写不同应用程序。JAVA和 JDBC的组合让程序员一旦编写好一个应用程序就可以到处运行
JDBC 访问数据库的原理是:INTERNET/INTRANET用户使用浏览器连接到本地或异地的WEB服务器上,下载含有JAVA小程序的HTML文档。如果JAVA小程序使用了JDBC ,浏览器运行的小程序可以直接与数据库建立连接如图(4-5)所示。
JDBC的实现
JDBC APE 是通过JAVA的类接口实现的,JDBC主要有两种接口,分别是面向程序开发人员的JDBC API和面向底层的JDBC Drive API,它们的功能如图(4-6)所示:
JDBC API 被实现成 JAVA.SQL 包,API层下面是为各种操作系统和硬件组合编写的数据库JDBCDriverManager(驱动器管理器),它是JAVA虚拟机的一部分,再下面是JDBC Driver(驱动器)。 JAVASOFT公司将JDBC驱动器分为四种:1)JDBC-ODBC桥, 2)专用API JAVA 驱动器, 3)网络纯协议JAVA驱动器, 4) 本地协议纯JAVA驱动器,JDBC-ODBC桥,
图4-5
专用API JAVA驱动器,均适用于局域网。
JDBC API是一系列抽象的接口,它使得应用程序员能够进行数据库连接,执行SQL声明,并且得到返回结果。
图中所示为一些最重要的接口,他们是:
java.sql.DriveManager 用来处理装载驱动程序并且为创建新的数据库连接提供支持,Drivermanager类作为JDBC的管理层,负责找到并装入与URL 指定的远程数据库相连,返回一个java.sql.connection 对象;
java.sql.Connection完成与某一指定数据库的连接;
java.sql.Statement 在一个给定的连接中作为SQL执行声明的容器,它包含了两个重要的子类型;
java.sql.PreparedStatement 用于执行预编译的SQL声明;
图4-6
java.sql.CallableStatement 用于执行数据库中存储过程的调用;
java.sql.Result 表示从数据库服务器返回的结果集。
下面的JAVA程序将连接预告ODBC数据源并执行一条SQL语句,返回的结果放在结果集对象RS中。
String url = “jdbc:odbc:Factory”;
Connection on =DriverManager.GetConnection(url,
“Username”,”passwrod”);
Statement stmt = on.CreateStatement();
ResultSet RS = stmt.ExecuteQuery(“SELECT Eno,Ename,Esex,FROM Clerk”);
JDBC数据库使用URL的指名规则。JDBCURL结构为“JDBC”(SUBPRO-PROTOCOL):(SUBNAME),其中SUB-PROTOCOL表示一个特定的数据库连接,SUBNAME的内容依赖SUBPROTOCOL,“JDBC:ODBC:FACTORY“指定一个ODBC数据源FACTORY。
JDBC Driver Interface
JDBC DRIVER API 面向驱动程序开发商的编程接口,对于大多数的数据库驱动程序来说,仅仅实现JDBC API 提供的抽象的类就可以了。即每一个驱动程序都必须提供对于java.sql.* 的主要接口的实现方法。
4. 各种接口技术的比较
虽然CGI、WEB SERVER API 和JDBC都能实现WEB与数据库的连接,但它们的工作原理是不同的:
CGI和API 是将WEB服务器与某一进程或API 相连,该进程或API 将得到的结果格式化为HTML文档,返回给WEB服务器,然后由WEB服务器将得到的HTML文档传给浏览器。就是说,与数据库的交互是由WEB服务器完成的。而在JDBC 中,浏览器将嵌于HTML 文档中的JAVA应用程序下载到能够运行JAVA程序的本地浏览器中加以运行。与数据库服务器的交互工作是由浏览器直接完成的。
表(4-1)对它们从不同的侧面进行了比较。
CGI API JDBC IDC
实现的灵活性
好 好 好 好
编程的复杂度
复杂 复杂 中等 简单
对程序员的要求
高 高 中等 低
开发时间
长 长 中等 短
可移植性
较好 差 好 差
CPU负担
重 较轻 较低 较低
平台有关性
有关 有关 无关 有关
表4-1
相比较而言,CGI接口应用灵活,开发工具丰富,功能广泛,技术相对成熟。CGI 是大家都支持的规范,但是用CGI 编程太复杂,一个简单的SELECT查询,用CGI实现就需要上百条语句;CGI 的运行效率也不高,并且要求程序员熟悉HTML。再加上与平台有关的缺点,所以CGI 已逐渐被新的规范所取代。
用WEB服务器API编写的程序运行效率高,但是,用API编程比用CGI还难,对程序员的要求更高。并且API致命的弱点是,各API间没有互通性,用一种API写的应用程序不能到另一种WEB服务器上运行,限制了使用范围。尽管个别公司(如ORACLE)推出了基于API的开发工具,在一定程度上解决了API开发困难的问题,但仍存在与API一样的弱点:与各自的WEB服务器捆绑的太死,缺乏通用性。
JAVA编程规范,接口清晰,开发效率高。JAVA代码在可移植性、安全性和可靠性等方面也有显著的优势,利用JAVA的多线程机制控制技术可以大大提高程序的执行效率。而且JAVA编译器是在客户端运行,开发人员能创建反馈迅速的JAVA APPLET,这是CGI 和API编程无法实现的。JDBC借鉴了ODBC 的思想,可以利用现成的ODBC驱动程序访问各种数据库,保护了原有的投资。重要的是,在数据库方面,所有的数据库厂商都宣布支持JDBC的标准,已推出或准备推出各自的JDBC驱动程序;在WEB服务器方面,除了MICROSOFT坚持自己的ACTIVEX外,其他厂商都宣布支持JDBC标准。
经过以上的分析、比较,对于此课题的实现,我采用了三层的BROWSER/SERVER结构体系,客户端使用JAVA APPLET编程技术,使用JDBC作为与数据库的接口,其数据库驱动程序为JDBC-ODBC Bridge。
第五章 课题方案的实现
5.1 总体构想
确定方案后,就开始具体的方案实施工作了。在这儿先介绍一下JAVA APPLET 的特点。JAVA APPLET 是一类特殊的JAVA程序,它嵌入在HTML语言中,可以随着主页发布到INTERNET上。利用它,用户可以非常简单地实现INTERNET上的程序编写,实现多媒体的用户界面或进行复杂的计算。
JAVA APPLET小程序访问数据库的方法有两种。 第一种方法是构造两级结构,所有的客户功能完全由JAVA APPLET来实现(见图5-1),使用专门协议纯JAVA驱动器,用户的SQL命令可以直接由APPLET传送到数据库,其结果也直接返回给用户。
WEB服务器
WEB客户机
JAVA APPLET HTTP
DATABASE
服务器 DB协议
图5-1
WEB
服务器
WEB客户机
JAVA APPLET HTTP
用户自定义协议
JAVA
服务器程序
(GATEWAY)
DATABASE 服务器
DB协议
图5-2
第二种方法是使用三级结构,可以使用JDBC-ODBC桥作为驱动器,这时需要一个独立的JAVA服务器程序作为网关,在APPLET和远端数据库服务器之间传递请求和响应(见图5-2)。
前一种方法中JAVA客户程序必修在能够支持销售商专用的数据库的协议层上执行。有该类型产品,如CONNECT SOFTWARE 的FASFORWARD 可直接访问SYSBASE,MS SQL服务器。
后一种方法JAVA服务器程序可以作为一个独立的JAVA应用程序,用封装在JAVA类库中的客户程序库函数来创建。这个服务器程序一方面通过用户定义的协议与客户端的JAVA APPLET 通信,另一方面通过本机的客户/服务器协议访问数据库服务器。
5.2程序各个功能模块的具体实现
方案的实施分为客户端程序和服务器端程序两部分。客户端由于要能够放在WEB页面上,故使用了JAVA APPLET 编程技术,而服务端则无此要求。下面我来分别讲述两者的实现过程,在此处我仅仅讲一下程序中最主要、关键的几个部分、其实现的大概过程,细节处不予缀述。
5.2.1 JAVA应用程序服务器
服务端程序的主要目的是创建监听客户连接的线程,当客户与服务程序连接上之后,客户程序会给服务程序发送请求,此时就由服务程序负责处理此请求,并且负责与数据库系统的通信和对数据库的操作。之后,再由服务程序将对数据库操作的结果返回给客户程序,显示在WEB页面上。
SERVER程序首先为每个服务(如连接、查询、修改等)创建不同的监听线程,每个线程都将创建一个服务器套接字(SOCKET),在指定的端口等待,用于监听客户的连接请求。这样做简化了代码,如果只使用一个服务器套接字(SOCKET),那么要执行所有处理的代码将是很复杂的。使用一个套接字处理全部的请求,需要客户N端传人标识请求的信息。允许每个服务在它自己的端口上提供服务,可以减少创建应用程序的代码数量。
系统的流程图如图(5-3):
开 始
创建监听线程
是否有用户连接? NO
YES
根据不同的端口号创建不同的服务线程
该服务线程接收用户的SQL请求进行数据库操作
根据不同的端口号创建不同的服务线程
该服务线程接收用户的SQL请求进行数据库操作
对结果集进行处理
再将数据库操作的结果经过SOCKET送给客户程序
此线程结束
相应的程序模块介绍如下:
1.创建一个线程,此线程创建一个套接字(SOCKET)对象,用于监听客户端的连接,可以为其指定一个端口号,此处是4700(可以任意,只要不与系统正在使用的冲突即可)。
connect c=new connect();
c.start();
Public class connect extends Thread{
public void run(){
try{
int i=0;
//创建套接字对象,端口号4700,监听用户的连接请求
ServerSocket server = new ServerSocket(4700);
System.out.println("Listening Port 4700........");
Socket client ;
//循环监听,等待客户的连接,收到用户的连接请求后,
建立SOCKET 对象
while (true){
client = server.accept();
i++;
2.当服务程序在指定的端口监听到客户的请求时,此监听线程将再为具体的服务建立一个新的线程。也就是说,每收到一个客户的请求,就为此客户建立一个新的线程为它服务,这样就做到了多线程、多用户,多个用户可以同时通过WEB服务器访问数据库。
/ /再为此客户的请求建立一个新的线程,由此线程提供具体的服务;
new ActionServerconnect(client).start();
}
}catch(Exception e){
System.out.println("Exception:"+e);
}
3. 为客户服务的线程的具体实现情况如下:服务线程通过数据库驱动程序与数据库建立连接,创建一系列的数据库对象,接收用户传来的SQL语句,进行数据库操作,之后,将操作的结果集进行处理,发送给客户程序,至此一次服务结束。
//线程
class ActionServerconnect extends Thread{
Socket client;
public ActionServerconnect(Socket client){
this.client = client;
}
public void run(){
try{
//用指定的数据库驱动程序jdbc-odbc Bridge,连接数据源
数据源名称: odbc_msora_nt;
String url="jdbc:odbc:odbc_msora_nt";
//加载数据库驱动程序JDBC-ODBC Bridge,与数据库连接时, DRIVER MANAGER 将试图使用此驱动程序;
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
//建立连接,用DRIVER MANAGER 的getConnection方法建立与URL指定的数据源的连接,若成功则返回一个CONNECTION类的对象,以后对这个数据源的操作都是基于此对象的。
Connection con =DriverManager.getConnection(url,”cimsnt”,”cimsnt”);
checkForWarning(con.getWarnings());
//获得 DatabaseMetaData对象,关于数据源的信息
DatabaseMetaData dma = con.getMetaData();
System.out.println("\n connectdb");
//创建Statement对象,用于查询语句的执行
Statement stmt = con.createStatement();
//执行查询语句,查询的结果返回一个ResultSet类的对象;
ResultSet crs;
crs = stmt.executeQuery("select distinct shebh from SM_T_quansfcd order by shebh");
4. 查询结果的处理。 查询结果都是放在ResultSet的对象中,ResultSet 对象包括一个由查询语句返回的一个表, 这个表中包含所有的查询
结果。对ResultSet对象的处理必须逐行地进行,而对每一行中的各个列,可以按任何顺序进行处理。
ResultSet对象维持一个指向当前行的指针。最初,这个指针指向第一行之前,ResultSet类的NEXT()方法使这个指针移向下一行,此时可以对第一行的数据进行处理。处理完毕后,再使用NEXT()方法将指针下移一行,继续处理下一行数据。NEXT()方法的返回值是一个BOOLEAN值,若为TRUE,则说明指针成功下移,可以对该行数据进行处理。若返回FALSE,则说明没有下一行,即结果集已处理完毕。
对每一行处理时,可以对各个列按任意顺序进行。ResultSet类的getXXX方法可以从某一列中获得结果。其中XXX是JDBC中的JAVA的数据类型。JAVA数据类型与SQL数据类型之间可以进行转换。
由于要将结果发送至客户端,所以要创建一个HASHTABLE数组,将ResultSet类的对象的数据存放在其中。
//取结果集的信息
ResultSetMetaData rsmd = crs.getMetaData();
//首先,将结果集的各个列名放在HASHTABLE中,取列名,向HASHTABLE表中放入结果集中的数据。在WHILE循环中调用ResultSet对象的NEXT()方法,扫过结果中的每一条记录。对于每一条记录,再用一个FOR 循环来遍历每一列。对第一个记录还需要创建适当的HASHTABLE对象以存放每一列数据,在循环中,检查记录数,并在处理第一条记录时,在数组的适当位置创建一个HASHTABLE对象。创建后,即可将数据添加到HASHTABLE表中。
int numCols=rsmd.getColumnCount();
String Colsname=null;
Hashtable Record[]; / /创建HASHTABLE对象
Record = new Hashtable[numCols];
for (int k=0;k
Record[k] = new Hashtable();
Record[k].put(newInteger(1),rsmd.getColumnLabel(k+1));
} //放入列名完毕
int i;
boolean have = false;
int j=0;
//开始放入数据
while (crs.next()){
have = true;
j++;
index++;
for (i=0; i String r = crs.getString(i+1);
if (r==null){
Record[i].put(new Integer(index),"NULL");
}else{
Record[i].put(new Integer(index),r);
}
}
}
5.创建输出流,用于发送HASHTABLE对象,利用OutputStream 和ObjectOutputStream对象将HASHTABLE对象传送给客户
OutputStream ostream = client.getOutputStream();
ObjectOutputStream out = new ObjectOutputStream(ostream);
out.writeBoolean(have);
if (have){
out.writeInt(numCols);
out.writeInt(j);
//向输出流中写入HASHTABLE对象,使其序列化
out.writeObject(Record);
}
//发送HASHTABLE表对象
out.flush();
out.close(); / /输出流关闭
}catch(Exception e){ / /例外处理
System.out.println("error:"+e);
}
}
有关问题:
在服务程序的设计上,使用了JAVA1.1中的一个新的功能,那就是通过网络的流机制发送整个对象。这是因为JAVA1.1引入了一个称为序列化的新概念。序列化机制允许你利用流使对象序列化。使用流和序列化操作,用户现在可以创建对象服务器来存储对象,并将其发送到所需的客户机上,这样就允许分布式处理。序列化开创了新的应用领域,包括对象服务器和高级特征存储。
5.2.2 数据源的配置
由于通过JDBC-ODBC BRIDGE 来连接数据源,也就是要通过ODBC来与数据源进行打交道,所以要建立相应的数据源。在本设计中使用了ORACLE数据库,其数据源的配置如下。
一.要在ORACLE数据库系统中建立起所要使用的数据,本设计中所用的数据来自南屯煤矿选煤厂CIMS应用工程,其大量的表已建好。
二.在ORACLE的SQL*NET Easy Configuration中建立与远程数据库的连接:
1) 打开SQL*NET Easy Configuration;
2) 选择ADD Database Alias项,确定;
3) 在Database Alias一项中输入数据库的别名,可自定,如ORANTM,确定;
4) 选择合适的网络协议用来与数据库建立连接,选择TCP/IP协议,确定;
5) 输入数据库系统所在的主机的IP地址或主机名,如202.119.199.77,确定;
6) 最后再确认一下你所输入的信息的正确性。
至此,与ORACLE 数据库系统的连接已建立起来。
下一步,在ODBC中建立数据源,以便于应用程序通过JDBC-ODBC BRIDGE 与数据库系统进行连接,存取数据。
1)打开控制面板,选择32位ODBC项;
2)选择ADD;
3)选择用于ORACLE的微软ODBC驱动器;
4)在数据源名称一项中输入名称,如“odbc_msora_nt”;
5)在连接字段一项中输入已建立好的与ORACLE 系统的连接的别名,如“ORANTM”;
6)确定后,数据源就已经配置完毕。
5.2.3 JAVA APPLET客户方程序的实现
客户方的程序是一个JAVA APPLET ,以便于随着网页发布到各个用户那儿去。客户方要实现与用户的交互工作,要有一个友好的用户界面,并且方便用户的使用。JAVA APPLET 通过套接字(SOCKET)与服务程序进行通信,传递请求,传送规范的SQL语句给服务程序,并且接收SQL语句执行的结果,进行显示。
相应程序各个功能模块介绍如下:
1. 首先要进行用户界面的初始化工作,建立起一系列选择框以方
便用户的使用。
界面上的设备号一项的选择内容,其数据要求要从数据库中实时第取出,再放在面板上。
//定义界面上的各个对象
public class whApplet1 extends Applet {
boolean isStandalone = false;
Label label1 = new Label();
Label label2 = new Label();
Label label3 = new Label();
。。。。。。
//初始化界面
private void jbInit() throws Exception {
this.setFont(new Font("Dialog", 3, 12));
this.setSize(new Dimension(448, 348));
this.setBackground(new Color(178, 201, 232));
label1.setFont(new Font("Monospaced", 3, 30));
。。。。。。
label4.setText("设备号:");
。。。。。。
p1.add(label3, new XYConstraints(52, 105, -1, -1));
p1.add(choice1, new XYConstraints(97, 62, 64, -1));
。。。。。。
//为设备号一项实时添加内容:该项要从数据库中的数据中得出,故要做一个查询操作。首先建立套接字(SOCKET),为其指定要连接的主机名或主机的IP地址,并且指定端口号,以便于与服务器进行通信。此项内容实质上是在数据库中做一个查询,将不同的设备号都查出来,再显示在此处。
try{
//创建套接字,与服务程序建立连接
Socket socket=new Socket("202.119.199.74",4700);
//建立输入流对象,用于接收服务方传来的数据流
DataInputStream sin = new DataInputStream(socket.getInputStream());
String readline;
int j;
//通过SOCKET读入流中的数值型数据,放在变量j中
j = Integer.parseInt(sin.readLine());
System.out.println(""+j);
//通过SOCKET读入流中的字符串型数据,也就是查询的结果:不同的设备号,放在变量readline中
readline=(String)sin.readLine();
//依次将查询的结果放在选择框中,完成初始化工作
for (int i=1;i<=j;i++){
readline = (String)sin.readLine();
choice5.addItem(readline);
}
}catch(Exception ee){
System.out.println("error:"+ee);
}
}
2.下面是客户程序的主体部分,也就是形成SQL语句发送SQL请求的
一部分,系统要根据用户的一系列选择生成SQL语句,并且发送给服务程序。
void button1_actionPerformed(ActionEvent e) {
//创建套接字(SOCKET),与服务程序建立连接
try{
Socket socket=new Socket("202.119.199.74",4701);
//建立输出流,用来发送SQL语句给服务程序
PrintStream os= new PrintStream(socket.getOutputStream());
//从APPLET上取得数据以构成SQL语句的条件
String date1y = choice1.getSelectedItem().trim();
String date1m = choice3.getSelectedItem().trim();
String date1d = textField1.getText().trim();
String date2y =choice2.getSelectedItem().trim();
String date2m = choice4.getSelectedItem().trim();
String date2d = textField2.getText().trim();
String shebh = choice5.getSelectedItem().trim();
String banc = choice6.getSelectedItem().trim();
//通过一系列的判断语句来组合不同的客户选择条件下的查询语句
if ((shebh.equals("全部"))&&(banc.equals("全部"))){
sq = "SELECT SHEBH,RIQ,MEIYBH,SHUIF,BANC FROM SM_T_QUANSFCD WHERE RIQ >= '"+date1y+"-"+date1m+"-"+date1d+" 00:00:00"+"' and RIQ <= '"+date2y+"-"+date2m+"-"+date2d+" 00:00:00'";
m="no";
System.out.println(m);
os.println(m);
os.flush();
}else if (( shebh.equals("全部"))&&!(banc.equals("全部"))){
sq = "SELECT SHEBH,RIQ,MEIYBH,SHUIF,BANC FROM SM_T_QUANSFCD WHERE RIQ >= '"+date1y+"-"+date1m+"-"+date1d+" 00:00:00"+"' and RIQ <= '"+date2y+"-"+date2m+"-"+date2d+" 00:00:00' and banc = '";
if (banc.equals("早")){ m="morning";}
else if (banc.equals("中")) { m = "noon";}
else if (banc.equals("晚")) { m="evening";}
os.println(m);
os.flush();
}else if (!(shebh.equals("全部"))&&(banc.equals("全部"))){
sq = "SELECT SHEBH,RIQ,MEIYBH,SHUIF,BANC FROM SM_T_QUANSFCD WHERE RIQ >= '"+date1y+"-"+date1m+"-"+date1d+" 00:00:00"+"' and RIQ <= '"+date2y+"-"+date2m+"-"+date2d+" 00:00:00' and shebh = '"+shebh+"'";
m="no";
os.println(m);
os.flush();
}
else {
sq = "SELECT SHEBH,RIQ,MEIYBH,SHUIF,BANC FROM SM_T_QUANSFCD WHERE RIQ >= '"+date1y+"-"+date1m+"-"+date1d+" 00:00:00"+"' and RIQ <= '"+date2y+"-"+date2m+"-"+date2d+" 00:00:00' and shebh = '"+shebh+"' and banc = '";
if (banc.equals("早")){ m ="morning";}
else if (banc.equals("中")) { m = "noon";}
else if (banc.equals("晚")) { m ="evening";}
os.println(m);
os.flush();
}
sql = sq;
System.out.println(sql);
//SQL语句写入输出流,准备发送
os.println(sql);
//刷新缓冲区,强迫发送SQL语句给服务程序
os.flush();
//建立输入流,用于准备接收服务程序传来的查询结果,由于结果集是放在一个HASHTABLE的对象中,所以,输入流也要具备读取对象的能力。
int numCols;
InputStream istream = socket.getInputStream();
ObjectInputStream in = new ObjectInputStream(istream);
//读取流中的结果集,并且进行处理,放在列表框中显示出来
boolean have = false;
have = (boolean)in.readBoolean();
if (have){
numCols= (int)in.readInt(); // 列数
int j;
j=(int)in.readInt(); // 行数
Hashtable r[] ;
r = (Hashtable[])(in.readObject());
for (int h=1;h<=j+1;h++){
String tmpstr="";
tmpstr = r[0].get(new Integer(h)).toString();
list1.addItem(tmpstr);
tmpstr="";
tmpstr = r[1].get(new Integer(h)).toString();
list2.addItem(tmpstr);
tmpstr="";
tmpstr = r[2].get(new Integer(h)).toString();
list3.addItem(tmpstr);
tmpstr="";
tmpstr = r[3].get(new Integer(h)).toString();
list4.addItem(tmpstr);
tmpstr="";
tmpstr = r[4].get(new Integer(h)).toString();
list5.addItem(tmpstr);
}
}else{
list1.clear();
list1.addItem("无此数据或输入有误!");
}
}catch(Exception ee){
System.out.println("error:"+ee);
}
}
3.图形报表的实现:JAVA的另一个优点就是在WEB上的强大的图形功能,这可以使WEB页面更加生动、活泼,同时也更能说明问题,更加直观。在本课题中,使用JAVA的图形功能来反映出一年中的煤样水分含量的变化趋势。
首先服务程序要进行数据的统计,执行这样一个查询:
for (int m=1;m<=12;m++){
double value=0;
String sql="select AVG(SHUIF) FROM SM_T_QUANSFCD WHERE RIQ >= '1998-"+m+"-1 00:00:00' AND RIQ <='1998-"+m+"-28 00:00:00'" ;
crs = stmt.executeQuery(sql);
}
通过SOCKET将结果送给客户程序,客户程序经过分析结果,根据一定的算法,将数据之间的关系体现在曲线的坐标上,就可以从曲线的长短上反映出统计数据的情况了,这里不再缀述。
4. 为了使各个列表框保持同步地显示结果,易于用户了解查询的结果:
void list3_mouseClicked(MouseEvent e) {
int i = list3.getSelectedIndex();
list2.select(i);
list1.select(i);
list4.select(i);
list5.select(i);
}
void list1_mouseClicked(MouseEvent e) {
int i = list1.getSelectedIndex();
list2.select(i);
list3.select(i);
list4.select(i);
list5.select(i);
}
void list2_mouseClicked(MouseEvent e) {
int i = list2.getSelectedIndex();
list1.select(i);
list3.select(i);
list4.select(i);
list5.select(i);
}
void list4_mouseClicked(MouseEvent e) {
int i = list4.getSelectedIndex();
list2.select(i);
list3.select(i);
list1.select(i);
list5.select(i);
}
void list5_mouseClicked(MouseEvent e) {
int i = list5.getSelectedIndex();
list2.select(i);
list3.select(i);
list4.select(i);
list1.select(i);
}
}
5.4系统的改进
系统的改进方向是客户端的数据动态显示。也就是,如果后台数据库中的此用户正在查询的数据发生了变化,比如,表中某些值由人工操纵发生了改变,那么,在该客户的浏览器端要能够实时地反映出来这一变化。
要实现这一步,我考虑可以从以下入手:
在服务程序方为每一个用户设立一个后台的进程或线程,始终在运行,它每隔一段时间就从数据库中取出该用户所使用的数据集,将最近的两次结果进行比较,如果发现有不同的地方,也就是两个结果集不同,那么就立即将最近的这一结果集再次发往客户端。客户端的接收进程或线程接收到新的数据后,进行显示的刷新,这样就实现了动态的数据显示。
由于时间的限制,我未能就这一课题继续深入地探讨下去,所提出的想法也没有经过验证,有不成熟的地方还请各位老师指点。