GB | BIG5
|
| 首頁 > 編程技術 > Java > 正文 |
 |
| JDBC基礎 |
| http://javaclub.yeah.net (2001-04-15 21:11:14) |
1. 介紹
許多開發者和用戶都在尋找Java程序中訪問數據庫的便捷方法。由Java是一個
健壯,安全,
易使用的,易理解且可以從網絡中自動download ,所以它成為開發數據庫應
用的一種良
好的語言基礎。它提供了C,C ,Smalltalk, BASIC, COBOL, and 4GLs的許多優
點。許多公司
已經開始在Java與DBMS的連接方面做工作。
許多Java應用開發者都希望能夠編寫獨立特定DBMS的程序,而我們也相信一個
獨立DBMS的
接口將使得與各種各樣DBMS連接變得最為便捷,開發更加迅速。所以我們認為定
義一個通用的
SQL數據庫存取框架,在各種各樣的提供數據庫連接模塊上提供統一的界面是十分
有意義的。這
使程序員可以面對單一的數據庫界面,使數據庫無關的Java工具和產品成為可
能,使得數據庫連
接的開發者可以提供各種各樣的連接方案。我們看到我們定義一個通用低層的,
支持基本SQL功能
的Java DataBase Connectivity (JDBC)API的緊迫任務。
幸運的是我們不必從頭設計一個SQL API。我們可以把我們的工作建立在 X/Open
SQL CLI (調用
層接口)之上(它也是Microsoft's ODBC 的基礎)。
我們主要任務是定義一個自然的Java接口來與X/Open CLI中定義的基本的抽象層
和概念連接。
JDBC API得到數據庫開發廠商,連接開發廠商,ISV,以及應用開發者的支持是十
分重要的。我們
相信把我們的工作建立在ODBC抽象層的基礎上將JDBC更加容易得到大家的接受。
而且從技術上來說,
ODBC是我們設計工作的一個良好基礎。
因為ODBC是一個C語言接口,所以ODBC在Java中直接使用不適當。從Java中來調用
C代碼在安全性,
健壯性,實現的方便,可移植性等等方面有許多不便。它使得Java在這些方面的
許多優點得不到
發揮。
我們已經在短期裡面實現了一個建立在ODBC上的API。長遠來看,我們可以通過其
他方式提供實現。
1.1. 注意
我們非常感謝在數據庫,數據庫連接和數據庫工具領域的許多早期的工作者。他
們為JDBC的早期草案
提供了很好的意見和建議。他們的工作對本規范起了不可估量的作用。
2. 目標與哲學
這個部分描述了指引這個API開發的目標以及哲學。
2.1. SQL 級 API
我們的主要目標是為Java定義一個“調用級”(call-level)的SQL接口。著意味著
我們主要的注意力
集中在執行原原本本的SQL語句並且取回結果。我們預計高層的API也將被定義,
這些可能將建立在基
層的接口上。這些高層接口包括象直接地、透明地把表裡面的數據影射到Java類
裡面,用語法樹表示
更加通用的查詢,以及Java內嵌的SQL語法。
我們希望大量的應用開發工具將使用我們的API。然而我們也希望程序員能夠使用
我們的API,尤其是
目前這樣在Java裡沒有任何其他手段(應該是說數據庫訪問手段)的情況下。
2.2. 遵循SQL
數據庫系統支持各式各樣的SQL語法和語義,它們相互之間在比較高級的功能例如
外部連接,內嵌過程
等方面並不一致,盡管我們能夠盼望著隨時間的推移這些部分的SQL可以獲得標準
化。同時我們採取這
樣的態度與立場:
In fact, an application query need not even be SQL, or it may be a
specialized
derivative of SQL, e.g. for document or image queries, designed for
specific DBMSs.
In order to pass JDBC compliance tests and to be
called "JDBC COMPLIANT ?" we require that a driver support at least
ANSI SQL-2 Entry
Level. This gives applications that want wide portability a guaranteed
least common
denominator. We believe ANSI SQL-2 Entry Level is reasonably powerful
and is reasonably
widely supported today.
l JDBC允許查詢表達式直接傳遞到底層的數據驅動,這樣一個程序可以獲得盡量
多的SQL功能,但是可
能被DBMS拒絕。事實上,一個程序的查詢甚至可以不是SQL的,或者是SQL的一個
特殊演化,例如:
為專門數據庫設計的文本或者圖形查詢。
l 為了通過JDBC兼容的測試,並且能夠被稱為JDBC兼容,我們要求一個驅動至少
支持ANSI SQL-2的標
準。這使得那些需要廣泛移植性的程序獲得一個最小的分母(這句話的原文是:
This gives
applications that want wide portability a guaranteed least common
denominator.)。
我們相信ANSI SQL-2是足夠強大的,並且是得到足夠支持的。
2.3. JDBC必須可以建立在現有的數據庫接口上
我們必須能夠保証 JDBC SQL API 能夠建立在普通的SQL API上,尤其是ODBC。這
些要求已經對這個
規范的一些部分產生了影響,尤其是對傳出參數(OUT parameter)和大數據塊的處
理。
2.4. 必須保証這個接口與JAVA系統的其他部分保持一致
目前對JAVA的積極回應已經十分熱烈。很大程度上是由這個語言標準以及標準
運行時庫被認為是一
致,簡單和強大的。我們將盡我們所能,提供這個Java數據庫接口,這個接口將
建立在Java內核現有
的這種風格,並且將進一步加強它。
2.5. 保持簡單
We would prefer to keep this base API as simple as possible, at least
initially. In
general we would prefer to provide a single mechanism for performing a
particular task,
and avoid provid-ing duplicate mechanisms. We will extend the API later
if any
important functionality is miss-ing.
我們將力爭使得基本的API盡量簡單,至少開始的時候是這樣的。一般來說,我們
希望對實現每個特定
的任務只提供一種方案,而避免提供多種方案。如果一些重要的功能遺漏了,那
我們在晚些時候將擴
充這個API。
2.6. 盡量保持強的、靜態的類型
我們希望這個JDBC API保持盡量強的類型檢查,使得盡可能多的類型信息可以靜
態地表達。著使得盡
可能多的錯誤可以在編譯的時候被發現。
由SQL本身是動態類型的,所以我們可能會在程序運行的時候遇到類型不能匹配
的問題。例如:
當一個程序員在希望SELECT返回一個整數,但是實際返回的是一個字符串
“foo”.但是我們依然希望
程序員把他們所希望的類型在編譯的時候就能夠表達清楚,這樣我們可以做盡可
能多的靜態檢查。
我們也希望在必要的時候能夠支持動態類型接口(見第四章)
2.7. 使普通任務簡化
我們希望普通的任務能夠是簡單的,而不一般的工作是可行的。
一個普通任務是指一個程序員執行一個簡單的沒有參數的SQL語句(例
如:SELECT,INSERT,UPDATE,DELETE),
然(例如SELECT)處理返回的具有簡單類型的元組。一個具有傳入參數(IN
parameter)的SQL語句
也是普通的。不那普通但是也是十分重要的情形是當程序員使用有INOUT,OUT參
數的SQL語句。我們
也需要支持讀寫幾兆字節對象的SQL語句,更特別一些的情形包括一個語句返回了
多個結果集合。
我們希望元數據(Meatdata)的使用很少的,只是那些熟練的程序員以及開發工具
才需要處理的問題。元
數據存取函數以及動態類型數據存取函數在這個文檔末尾,一般的程序員可以不
必關心這些章節。
2.8. 不同的功能讓不同的方法(函數)來實現
(“方法”的原文是:method,這樣翻譯是跟VB的)一種界面設計風格是使用很
少的過程,提供許多作
為參數傳遞的控制標志,這樣它們可以用來影響很大一個范圍內的各種行為。來
表達不同的功能。這
趨向與使用很多的方法,但是每個方法都比較同意理解。
一般來說,Java內核類使用不同的方法(method)。這個步驟的主要優點是開始
學習基本界面的程序
員可以不必被那些與復雜功能相關的參數所困擾。我們力圖在JDBC接口上也採用
相同的策略。一般來
說採用不同的方法而不是採用不同的標志和多用途的方法。
3. 接口概貌
接口分為兩個層次,一個是面向程序開發人員的JDBC API。另外一個是底層的
JDBC Driver API。
3.1. JDBC API
JDBC API 被描述成為彝族抽象的Java接口,似的應用程序遠可以對某個數據庫打
開連接,執行SQL
語句並且處理結果。錯誤! 嵌入對象無效。
最重要的接口是:
l java.sql.DriverManager 處理驅動的調入並且對產生新的數據庫連接提供支
持。
l java.sql.Connection 代表對特定數據庫的連接。
l java.sql.Statement 代表一個特定的容器,來對一個特定的數據庫執行SQL
語句。
l java.sql.ResultSet 控制對一個特定語句的行數據的存取。其中
java.sql.Statement
又有兩個子類型:
1. java.sql.PreparedStatement 用執行預編譯的SQL語句。
2. java.sql.CallableStatement 用執行對一個數據庫內嵌過程的調用。
下面的章節對JDBC是如何運行的提供了更多描述,整個定義見第13章。另外
第15章描述了系統如果獲取數據庫的元數據信息。
3.2. JDBC Driver API
java.sql.Driver在第9章有完整的定義了.大部分JDBC驅動只需要完成這些JDBC
API所定義的
抽象類就可以了。特別地,所有的driver必須提供對java.sql.Connection,
java.sql.
State-ment, java.sql.Prepared-Statement, and java.sql.ResultSet的實
現。如果
目標DBMS提供有OUT參數的內嵌過程,那還必須提供
java.sql.CallableStatement 接口。
每個database driver必須提供一個類:java.sql.Driver以使得系統可以由
java.sql.DriverManager來管理。
一個顯然的driver是在ODBC之上提供對JDBC的實現,從而提供與ODBC接口的
JDBC-ODBC 橋,
就象前面的圖所顯示的.由JDBC放在ODBC之,所以實現起來簡單而且高效。另
外一個有用的驅動
直接接觸數據庫無關的網絡協議。發布一個協議允許多個服務器實現的方法,例
如在ODBC或者特定的
DBMS上(盡管已經有了一些使用固定協議的產品,但是我們不打算對它們實現標
準化。),是可取的。
4. JDBC使用場合
Before looking at specifics of the JDBC API, an understanding of
typical use scenarios is help-ful. There are two common scenarios
that must be treated differently for our purposes: applets and
applications.
在看JDBC API之前了解一下典型的使用場合是有幫助的。通常有兩種情形必須分
別對待:
applet和application.
4.1. Applet
目前Java使用的最多的從網絡中下載的applet,它們作為web文件的一個部分。當
中有數據庫存取
applet和能夠使用JDBC來接觸數據庫的applet。
例如,一個用戶可能下載一個顯示股票歷史價格圖的applet。這個applet通過
internet來從關系
數據庫中獲得股票歷史價格。最一般的情況裡面,對applet的使用是通過不可靠
的邊界的。例如從
另外一個公司或者Internet上獲得這些applet。是稱這個情況為"Internet"場
合。然而applet
也可能通過局域網下載。在這個情況裡面,客戶機的安全都還是一個問題。
典型的applet在幾個方面與傳統的數據庫應用程序有所不同:
1. 不可靠的applet被嚴格地限制在他們被允許執行的的操作上。特別地,不允許
他們存取本地的
文件,切不允許他們對任意的數據庫建立網絡連接。
2. 就標識和連接網上數據庫來說,Internet環境裡面的applet面臨新的問題。
3. 當數據庫可能與你相隔萬裡的時候,效率的考慮也有所不同了。與局域網相
比,Internet上
數據庫applet可能會碰到十分不同的反應時間。
4.2. Application
Java也可以用來建立普通的應用,從而想一般的應用一樣在客戶機上使用。我們
相信隨著開發工具
越來越多,人們開始認識到提高程序生產效率的必要性,以及Java的其他優點,
Java的這種用法將
越來越流行。在這種方式裡面,Java的代碼是可以信賴的,且被允許讀寫文件打
開網絡連接等等,
就想其他的應用程序代碼一樣。
也許這些Java應用使用的最多的是在一個公司內部或者在Intranet上,所以不妨
成為Intranet場合。
例如一個公司希望利用Java及其GUI構件工具來建立他的基合作數據模式的合作
軟件。這些應用
程序將存取局域網或者廣域網的數據。Java應用可以作到這些。
Java應用程序場合和Intranet場合與applet場合有諸多不同。例如標定一個數據
庫最自然的方式是
用一個數據庫的名字,就象"Customers" 和"Personnel"這樣。然用戶希望系統
能夠定位具體的
機器,DBMS,JDBC driver,和Java應用程序。
4.3. 其他場合
還有其他一些有趣的場合:
1. 已驗証的applet(Trusted applets)是指那些已經被Java虛擬機器認定是可
以信賴的applet。
他們之所以被認為是可信的是因為他們已經對上了特定的密匙,或者用戶認為從
特定來源來的applet
是可信的。在安全的方面上他們與應用(appliction)相同,但是其他方面(例
如定位一個數據庫)
與則與applet相似。
2. 與直接從Java GUI出發用客戶/服務器模式來度曲DBMS服務器不同,三層存取
方式可能被使用。
在這個場合裡面,Java應用程序對中間層的服務發出調用,中間層的服務在網
上,它又再去調用數據庫。
這些調用可能通過RPC (remote procedure call)或者ORB (object request
broker )。在這兩種場
合裡面,中間層最好使用一個對象變化。我們希望三層結構會變得越來越普遍,
因為對MIS管理者來說,
這可以使得他們有機會在公共數據庫上顯式地定義合法操作等。同時三層結構可
以提供許多效率上的
好處。
目前中間層一般用C或者C 這樣的語言來完成。通過優化編譯器把把Java 字節
代碼翻譯成為高效的
機器代碼,中間層也可以用Java來實現。Java有許多優良特性(健壯性,安全
性,多線程)可以達到
中間層需要達到的目的。
5. 安全性考慮
作為網絡上的語言JAVA必須十分注安全性的考慮。基上面的討論,JDBC的兩種
主要使用場合裡面,我們
必須考慮安全性問題:
l 在Java applications的場合裡面Java代碼是本地的,所以也是"trusted"
l 沒有驗証的Java applet代碼不可以存取本地的以及其他網絡的數據。
5.1. JDBC 和未驗証的applet
JDBC首先必須符合JAVA的一般安全規則。另外:
l JDBC 必須認為沒有驗証的applets是不可靠的。l JDBC 不可以讓不可靠的
applets存取
本地數據庫。
l 一個已經向JDBC DriverManager注冊的是JDBC Driver只能存取它所來的數據
源。
l 一個applet也只能向它所Download來的服務器來存取數據。
如果JDBC驅動層如果完全確信對一個數據庫服務器打開連接不會引起認証或者權
限問題
(可能由網上隨機主機上運行的程序引起),那它就允許applet打開這樣的連
接。數據庫服務器
不通過IP地址來限制存取是相當少的,主要是為了舉例。(當心,這一段話我可
能翻譯反了!!!
大家看看原文。)
這些限制是相當煩瑣的。不過他們與對一般applet的限制是一致的我們沒有必要
放開這些限制。
5.2. JDBC 和Java應用程序
對一個普通的Java應用程序(例如全部用Java代碼而不是不可靠的applet )JDBC將從本地的類路
徑裡面獲得驅動,並且允許應用程序自由存取文件,遠程服務器等等。但是和applet一樣,如果由
某些原因一個沒有驗証的sun.sql.Driver類從遠程的來源裡面獲得,那這個驅動只能和相同地方
來的代碼配合。
5.3. Driver的安全責任
JDBC driver可能在各種情況下使用,所以驅動的編制者遵循一定的簡單的安全規則,從而避免
applet做非法的數據庫連接。如果所有的驅動都象applet一樣從網上下載,那這些原則將是
不必要的,因為普通的安全規則已經對它做了限制。但是驅動的編寫者必須記住一旦他們的驅動
獲得成功,用戶將在本地磁盤安裝這些驅動,那驅動將成為Java環境中一個被信任的部分,所以
必須確信它不會被來訪的applet所濫用。所以我們鼓勵所有的驅動編寫者必須遵循一定安全原則。
所有這些原則都是在連接打開的時候使用。這正式驅動和虛擬機器檢查當前調用者是否真的可以與
指定的數據庫連接的時刻。一旦連接建立就不必做更多的檢查了。
5.3.1. 分享TCP/IP連接的時候必須謹慎
如果一個JDBC驅動試圖打開一個 TCP 連接,那這個打開會被Java 安全管理機制自動檢查。
這個機構會檢查當前調用棧裡面有沒有applet,如果有那就限定它可以訪問的機器集合。所
以一般地JDBC驅動可以把TCP建立檢查留給Java虛擬機。但是如果一個JDBC驅動試圖在多個數據庫
連接之間共享一個TCP連接,那驅動就必須自己負責檢查每個調用者是否真的被允許與目標數據庫
聯系。例如如果我們為applet A打開了一個通往機器foobah 的TCP連接,這並不意味著applet B
被自動允許來共享這個連接。applet B可能沒有任何訪問機器foobah的權力。所以在允許某個程序
重用一個現成的TCP連接之前,JDBC 驅動必須通過安全機構來檢查當前的的調用者是否可以訪問這
個連接。通過下面的代碼可是實現這個功能。
SecurityManager security = System.getSecurityManager();
if (security != null)
{
security.checkConnect(hostName, portNumber);
}
如果連接是不允許的,那Security.checkConnect方法將產生一
個java.lang.SecurityException。
5.3.2. 檢查所有的本地文件訪問
如果一個JDBC取得需要訪問本地機器上的數據,那他必須確
信調用者是被允許打開這個文件的。例如:
SecurityManager security = System.getSecurityManager();
if (security != null)
{
security.checkRead(fileName);
}
如果對特定文件的訪問是不允許的,那Security.checkRead方
法將產生一個java.lang.SecurityException。
5.3.3. 作好最壞的準備
一些驅動可能使用本地的方法來橋接底層數據庫程序。則這些
情況裡面判斷那些本地文件將被底層函數所訪問是困難的。
在這些環境裡面用戶必須作好最壞的打算,並且否決所有下載
applet所發出的數據庫存取,除非驅動可能完全確信將要做存取
是沒有問題的。
例如一個JDBC-ODBC橋接器必須檢查ODBC數據源的的名
稱,確保applet只可以訪問它的“生源地”。如果對有的名字中
不能判斷出數據源的主機名,那只能否決這個訪問。
為了決定一個當前的調用者是可以信賴的應用還是一個
applet,JDBC驅動必須能夠檢查這個調用者是否可以寫一個隨
機的文件:
SecurityManager security = System.getSecurityManager();
if (security != null)
{
security.checkWrite("foobaz");
I. }
(http://www.fanqiang.com)
進入【UNIX論壇】
|
|
| 相關文章 |
|
|
|
|
 |
★ 樊強制作 歡迎分享 ★ |