第1部分:应用程序连接数据的简单方法
前言
你想不想写自己的JDBC驱动,或者是否想把现在的JDBC驱动转换成Type3的驱动呢?Type3 的驱动主要用于无需客户端设置的Internet/Intrant应用程序中,并且提供灵活的系统治理工具。本文中Nitin Nanda 和 Sunil Kumar描述了JDBC驱动的架构并概略讲解了Type3 JDBC驱动的三层结构。并演示了如何创建自己的Type3 JDBC驱动。
在Java中访问数据库系统你需要一个JDBC驱动。你可以自己写Type1到Type4的JDBC驱动,可以是纯Java的方式或者使用Java结合本地接口方法的复合方式。产品化的方式趋向于利用纯Java技术创建Type3或Type4的驱动程序。在Internet应用程序中访问数据库的效率和稳定性成为了要害因素,这时Type3 JDBC驱动显示出了它的优势。所以,要开发高效的、易部署的Internet应用,你通常需要将现在的Type1或Type2类型的JDBC替换成Type3类型的。
整个文章分为3个部分:
1.应用程序连接数据库的简单方法。
2.使用自定义的JDBC驱动编译、部署、访问数据。
3.通过高级的日志功能、连接池、预处理数据集增强自定义的JWDriver的性能。
在这三个部分中,我们首先介绍了我们自己的Type3 JDBC驱动的结构和设计(第一部分),然后讲了如何实现和部署整个驱动(第二部分),最后讲解了如何在其中增加一些高级特性,比如SQL日志、连接池等(第三部分)。
注重:
在开始之前,也许你可以先看一下Nitin Nanda's的"JDBC Drivers in the Wild",这更有利于你理解JDBC驱动。
JDBC驱动的结构
JDBC为通用的数据库访问提供了一种程序级的接口。在一个特定的数据库环境下使用JDBC API你需要一个JDBC驱动来完成他们直接的协调运行。JDBC被分为四种类型或者说层次。每一个类型都有一个JDBC实现,以便满足日益增加的对平台独立性、执行效率和可治理性的要求。这四种类型分别是:
Type1:JDBC-ODBC(开方数据库连接)桥。
Type2:本地API,部分的Java驱动。
Type3:网络协议,完全的Java 驱动。
Type4:本地协议,完全的Java驱动。
所有的JDBC驱动都要实现下面四个JDBC类:Driver、Connection、Statement和ResultSet。包含在java.sql包种DriverManager类用于治理被加载的驱动。客户端应用程序通过它获得数据库连接。JDBC的Driver通过下面的方法加载:
Class.forName("com.jw.client.JWDriver");
当这个Driver被加载时它的staic部分的代码就会执行,通过DriverManager注册这个驱动。现在,只要客户端应用程序通过DriverManger.getConnection()方法,DriverManager就会转而调用Driver.connect()方法。每一个JDBC驱动必须实现java.sql.Driver接口。所以,JDBC驱动的Driver.connect方法会首先检测当前的驱动Url是否正确,然后会通过connet()方法返回一个Connection对象。
简单Type3驱动的结构
为了向你展示Type3驱动的内容结构,我创建了一个自己的Type3JDBC驱动。我们的Type3驱动是基于网络协议、完全Java实现的,它分为3个层次,同时向你展示了JDBC是如何通过中间层的网络协议进行通信的。中间层服务讲请求传输(直接或间接的)给特定的数据库本地连接接口,然后通过这个接口将请求传输到数据库服务器。中间层用Java实现,数据库访问的实现通过JDBC-ODBC桥。
JDBC Type3 的结构
对于applet,客户层驱动文件位于中间层服务器,并且可以直接下载。在JDBC驱动种RMI提供网络协议服务,负责驱动的客户端和服务端的通信。JDBC-ODBC桥使得JDBC请求可以传输到数据库服务器。
驱动的客户层为客户端程序提供了标准的JDBC接口,包括实现了java.sql.Driver接口的Driver类。同时还包含了JDBC的Connection、Statement、Result接口的实现。
客户端应用程序,比如applet,可以使用Type3驱动的客户层类进行开发,因为它实现了标准的JDBC接口拥有标准的JDBC功能。客户层类的Driver在内部会维护与中间层提供的远程接口之间的通信。这些远程接口提供了客户端传输JDBC请求要用到的基本方法。应用程序会调用已经实现了的Driver中的JDBC方法,随后这些调用会通过RMI发送到中间层。所有Driver类的客户层通过中间层来治理内部的RMI通信。
驱动的服务层是一个RMI服务器,它通过JDBC-ODBC桥来和数据库进行通信。驱动的服务层包含4个远程接口以及它们的实现,这些远程接口分别为JDBC的Driver、Connection、Statement和Result提供了访问接口。实现这些远程接口的类会在内部维护JDBC-ODBC的桥驱动的Connection、Statement和Result对象。当客户层类调用远程接口的时候,远程接口的实现使用内部的JDBC对象与数据库通讯。
现在你已经了解了Type3 JDBC驱动的接口,下面让我们进一步的深入到客户层和服务器层中。
JDBC类驱动
为了实现Type3 JDBC驱动,我们必须创建客户层和中间层。客户层类位于com.jw.client包中,中间层位于com.jw.server包中,让我们先来看看客户层。
客户层类
客户层包com.jw.client中包含下面几个类:
com.jw.client.JWDriver类:JDBC驱动(Driver)的实现类。
com.jw.client.JWConnection类:JDBC连接(Connection)的实现类。
com.jw.client.JWStatement类:JDBC表达式(Statement)的实现类。
com.jw.client.JWRseultSet类:JDBC结果集(ResultSet)的实现。
如所示,它描述了客户层和中间层Driver和Connection类之间的关系。
Driver和Connection类
让我们仔细的看看JWDriver类的内部:
JWDriver类
com.jw.client.JWDriver类实现了java.sql.Driver接口,它提供了通过DriverManager类注册自己并创建数据库连接的方法。这个类实现了远程Driver的封装以便提供JDBC驱动接口。在应用程序中通过下面的方法调用可以加载JWDriver:
Class.forName("com.jw.client.JWDriver");
当它通过DriverManager类加载后,上面的代码中forName方法会调用JWDriver类的static部分的代码。下面显示的代码中的static部分:
static{try{// Register the JWDriver with DriverManagerJWDriver driverInst = new JWDriver();DriverManager.registerDriver(driverInst);System.setSecurityManager(new RMISecurityManager());}...}
JWDriver类同时还维护一个远程驱动的引用,com.jw.server.IremoteDriver,它位于中间层服务器。远程驱动的引用为JWDriver创建了数据库的连接。所以当应用程序需要获得一个数据库连接的时候就调用DriverManager.getConnection()方法,这时DriverManager的JWDriver.connect()方法会通过远程驱动的引用获得一个数据库连接。
简而言之,JWDriver.connect()方法完成如下超作:
比较客户端程序传递的URL假如是一个不匹配的URL就返回一个null。
假如不存在远程驱动引用就通过Naming.lookup()方法创建一个。JWDriver.connet()方法控制远程驱动来创建数据库连接。:
if(remoteDriver == null){remoteDriver= RemoteDriver)Naming.lookup("rmi://"+serverName+":1099"+"/RemoteDriver");}
创建、使用如上方法创建的数据库连接,并将创建的数据库连接返回给调用它的应用程序。RemoteDriver.getConnetion()方法是中间层JDBC驱动的远程调用,从中间层获得的远程Connection作为一个应用保存在JWConnection类对象中。JWConnection类可以通过下面的方法获得:
{IRemoteConnection remoteConInstance =(IRemoteConnection)remoteDriver.getConnection();localConInstance = new JWConnection(remoteConInstance);...return (Connection)localConInstance;}
下面我们一起来仔细的看看JWConnection类。
JWConnection类
Com.jw.client.JWConnection类实现了Connection接口,而且它还包含一个远程服务器IremoteConnection接口的引用。
客户端程序中的JWDriver.connect方法可以得到JWConnection对象的引用并创建一个JWConnection对象。这样客户端就可以通过JWConnection对象任意的调用JDBC Connection接口的方法了。JWConnection在内部调用远程服务器的Connection。比如当客户端调用conn.createStatement()方法时(conn是一个JWConnection的引用),其内部会调用一个RemoteConnection.createConnection()方法,并返回一个远程的Statement引用;JWConnectoin的createStatement方法会创建一个JWStatement对象;最后一个JWStatement对象会返回个客户端,这个对象中包含的Statement的引用:
public Statement createStatement() throwsSQLException{try{IRemoteStatement remStmt =(IRemoteStatement) remoteConnection.createStatement();JWStatement localStmtInstance = new JWStatement(remStmt);return (Statement)localStmtInstance;}}
描述了客户层和中间层中Connection和Statemennt类之间的关系。
Connection和Statement之间的关系
下面再让我们来看看JWStatement类
JWStatement类
com.jw.clent.JWS