国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

如何寫自己的Type3JDBC驅動

2019-11-18 16:25:05
字體:
來源:轉載
供稿:網友

  摘要:原文連接:http://www.javaworld.com/javaworld/jw-05-2002/jw-0517-jdbcdriver.Html? 本文屬于個人愛好翻譯請尊重原作版權
如何寫自己的type3 JDBC 驅動


第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驅動。如圖1所示,我們的Type3驅動是基于網絡協議、完全Java實現的,它分為3個層次,同時向你展示了JDBC是如何通過中間層的網絡協議進行通信的。中間層服務講請求傳輸(直接或間接的)給特定的數據庫本地連接接口,然后通過這個接口將請求傳輸到數據庫服務器。中間層用Java實現,數據庫訪問的實現通過JDBC-ODBC橋。

圖1 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)的實現。
如圖2所示,它描述了客戶層和中間層Driver和Connection類之間的關系。

圖2: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 DriverManager
JWDriver 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() throws
SQLException
{
try
{
IRemoteStatement remStmt =
(IRemoteStatement) remoteConnection.createStatement();
JWStatement localStmtInstance = new JWStatement(remStmt);
return (Statement)localStmtInstance;
}
}

圖3描述了客戶層和中間層中Connection和Statemennt類之間的關系。


圖 Connection和Statement之間的關系

下面再讓我們來看看jwstatement類
JWStatement類
com.jw.clent.JWStatement類實現了JDBC Statement接口,同時引用了遠程服務器的Statement接口。這個類封裝了遠程Statement存根,它提供了JDBC Statement接口,JWConnection.createStatemnt()方法創建了JWStatement對象并返回給客戶端。這樣客戶端就可以使用JDBC Statement接口提供的所有方法,在內部JWStatement調用了遠程的Statement。比如客戶端調用stmt.executeQuery()方法,這個方法內部會調用RemoteStatement.executeQuery()方法并返回一個ResulstSet引用。最終,JWResultSet對象會返回到客戶端,這個對象包含了ResultSet的引用:
public ResultSet executeQuery(String sqlQuery)
throws SQLException
{
try
{
IRemoteResultSet remoteRsInstance =
(IRemoteResultSet) remoteStmt.executeQuery(sqlQuery);
JWResultSet localRsInstance = new JWResultSet(remoteRsInstance);
return (ResultSet)localRsInstance;
}
catch(RemoteException ex)
{
throw(new SQLException(ex.getMessage()));
}
}

圖4描述了客戶層和中間層中Statement和ResultSet類之間的關系。

圖4 Statement和ResultSet類之間的關系

下面我們來看看jwresultset類。
JWResultSet類
com.jw.clent. JWResultSet類實現了JDBC ResultSet接口,同時引用了遠程服務器的ResultSet接口。這個類封裝了遠程ResultSet存根,它提供了JDBC ResultSet接口。JWStatement.executeQuery()方法創建想客戶端返回一個JWResult對象,它包含了Result接口的引用。因此客戶端程序可以使用JDBC Result提供的任何方法,JWResult對象內部會調用遠程服務器的ResultSet。比如當客戶端調用rs.next(rs一個一個JWResultSet對象的引用),next()方法內部會調用RemoteResultSet.getNextRow(),這個方法會返回一個包含行數據的數組。當客戶端調用rs.getString(1)方法時會返回保存在JWResultSet中行數據的當前值。
public class JWResultSet implements
java.sql.ResultSet
{
// The current ResultSet data row
PRivate Object[] row;//自己替換[]
...
public boolean next() throws SQLException
{
try
{
// Get the current data row from remote
ResultSet
// All the getXXX methods will get data from
local 'row'
row = remoteResultSet.getNextRow();
}
catch(Exception ex)
{
return false;
}
if(row == null)
{
return false;
}
return true;
}
}


中間層類
中間層類位于com.jw.server包中,包括下面幾個類:
        com.jw.server.RemoteDriverImpl類:這是一個驅動類它負責獲得數據庫連接,同時作為RMI服務器。
        com.jw.server.RemoteConnectionImpl類:是一個Connection 類,并且它負責獲得JDBC Statement。
        com.jw.server.RemoteStatementImpl類:是一個Statement類,并且它負責獲得JDBC ResultSet。
        com.jw.server.RemoteResultSetImpl類:是一個ResultSet類。

下面我們詳細分析每個類
RemoteDriverImpl
RemoteDriverImpl扮演一個RMI服務器(它繼承了UnicastRemoteObject)并向JDBC驅動客戶端提供了getConnection()方法。圖2顯示了RemoteDriverImpl的其他類與接口之間的關系。
com.jw.server.IremoteDriver是一個擴展了Remote的接口,它提供了getConnection()方法。這個方法創建JDBC Connection并作為一個IremoteConnection的引用返回給客戶端。
由于RemoteDriverImpl同時還是JDBC驅動服務器的RMI服務器,它會讀取ODBC的數據源名稱(DSN),從部署在服務層中的DriverSettings.properties
文件讀取用戶名和密碼。
這些值可以創建一個JDBC Connection,此外,RemoteDriverImpl可以通過名稱服務“RemoteDriver”注冊自身,所有JDBC 的客戶層可以通過Naming.lookup()方法與服務端連接。然后它會加載JDBC-ODBC橋來創建數據庫連接:
public static void main(String args[])//自己替換[]
{
System.setSecurityManager(new RMISecurityManager());
try
{
// Get the data source name, data source user, data
source
// PassWord and log level
ResourceBundle settingsBundle =
ResourceBundle.getBundle(
"DriverSettings");
DSN = settingsBundle.getString("DSN");
dsUser = settingsBundle.getString("User");
dsPassword = settingsBundle.getString
("Password");
// Create a RemoteDriverImpl instance to register
with naming service
RemoteDriverImpl serverInstance = new
RemoteDriverImpl();
Naming.rebind
("RemoteDriver",serverInstance);
// Load the JDBC-ODBC Bridge driver
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
}
...
}

getConnection()方法創建了JDBC-ODBC連接,然后返回RemoteConnectionImpl對象遠程接口的引用來控制JDBC-ODBC連接:
public IRemoteConnection getConnection()
throws RemoteException,SQLException
{
String URL="jdbc:odbc:"+DSN;
Connection sqlCon =
DriverManager.getConnection(URL,dsUser,dsPassword);
RemoteConnectionImpl ConnectionInstance =
new RemoteConnectionImpl(sqlCon);
return (IRemoteConnection)ConnectionInstance;
}

下面讓我們來看看RemoteConnectionImpl。
RemoteConnectionImpl類
RemoteConnectionImpl繼承了UnicastRemoteObject類并實現了IremoteConnection接口(圖2、3顯示了RemoteConnectionImpl類的其他類和接口的關系)。IremoteConnection接口提供了創建JDBC Statement和關閉數據庫連接的方法,RemoteConnectionImpl同時封裝了傳入構造中的JDBC連接。
createStatement()創建了JDBC-ODBC Statement并返回RemoteConnectionImpl對象的引用來控制JDBC-ODBC Statement:
public IRemoteStatement createStatement() throws
RemoteException,SQLException
{
RemoteStatementImpl StmtImplInstance = new
RemoteStatementImpl(sqlConnection.createStatement());
return (IRemoteStatement)StmtImplInstance;
}

接下來closeConnection()方法通過內部封裝的close()方法關閉JDBC Connection:
public void closeConnection() throws
RemoteException,SQLException
{
sqlConnection.close();
}

下面再看RemoteStatementImpl。
RemoteStatementImpl類
如圖3、4中顯示的RemoteStatementImpl類,它繼承了UnicastRemoteObject類并實現了IremoteStatement接口。這個接口提供了創建JDBC ResultSet和關閉Statement對象的方法。RemoteStatementImpl同樣封裝了闖入構造的Statement對象。
executeQuery()方法創建了JDBC-ODBC的ResultSet并返回一個RemoteStatementImpl對象的引用來控制JDBC-ODBC的ResultSet:
public IRemoteResultSet executeQuery(String Query)
throws RemoteException,SQLException
{
ResultSet rs = sqlStatment.executeQuery(Query);
RemoteResultSetImpl remoteRs = new
RemoteResultSetImpl(rs);
return (IRemoteResultSet)remoteRs;
}

close()方法簡單的關閉了JDBC Statement對象:
public void close() throws RemoteException,
SQLException
{
sqlStatment.close();
}

最后再來看看RemoteResultSetImpl類。

RemoteResultSetImpl類
RemoteResultSetImpl繼承了UnicastRemoteObject類并實現了IremoteResult接口(圖4 顯示了RemoteResultSetImpl類的其他類和接口的關系)。IremoteResult接口獲得JDBC ResultSet行數據并關閉ResultSet對象。RemoteResultSetImpl同樣封裝了構造中的ResultSet對象。
getNextRow()方法返回一個包含對象數組的JDBC ResultSet給客戶端JWResultSet,如果ResultSet不包含任何數據會返回null:
public Object[] getNextRow() throws
RemoteException,SQLException//自己替換[]
{
// Return null if all data has already been
iterated
if(sqlRs.next() == false)
return null;
// Prepare the data row in an array of Objects
Object []row = new Object[colNum];//自己替換[]
for(int i = 1; i <= colNum; i++)
{
row[i-1] = sqlRs.getString(i);//自己替換[]
}
return row;
}


close()方法會關閉ResultSet對象:
public void close() throws
RemoteException,SQLException
{
sqlRs.close();
}

以上就是中間層中的所有類。

type3 總結
在這篇文章中,我向你展示了Type3 JDBC驅動的結構。驅動創建了客戶層和服務層組件,并使用RMI實現它們之間的通信。我們還演示了客戶層的不同對象如何通過引用與服務層中的遠程對象交互。
在第2部分我會向你展示如何使用和部署這里創建的Type3驅動。我們將提供一個簡單的應用程序,并通過序列圖的方式向你展示驅動是如何加載的,如何創建一個JDBC Connection,如何創建一個 JDBC Statement。

(出處:http://m.survivalescaperooms.com)



發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 安阳市| 团风县| 临邑县| 商丘市| 江孜县| 洛宁县| 禄丰县| 微山县| 和硕县| 元氏县| 城步| 华阴市| 依兰县| 喀什市| 郁南县| 台北县| 天台县| 定安县| 武清区| 特克斯县| 涪陵区| 巴青县| 商南县| 奈曼旗| 金门县| 泾源县| 淮滨县| 亚东县| 剑阁县| 沙河市| 伊金霍洛旗| 胶州市| 浪卡子县| 肥东县| 勐海县| 鄂托克前旗| 泗阳县| 庄河市| 固阳县| 资源县| 天水市|