JSP學習——全面解析JDBC(2)
2024-09-05 00:19:30
供稿:網友
如何建立jdbc連接?
connection 對象代表與數據庫的連接。連接過程包括所執行的 sql 語句和在該連接上所返回的結果。一個應用程序可與單個數據庫有一個或多個連接,或者可與許多數據庫有連接。
1. 打開連接
與數據庫建立連接的標準方法是調用drivermanager.getconnection方法。該方法接受含有某個url的字符串。drivermanager類(即所謂的jdbc管理層)將嘗試找到可與那個url所代表的數據庫進行連接的驅動程序。drivermanager類存有已注冊的driver類的清單。當調用方法getconnection時,它將檢查清單中的每個驅動程序,直到找到可與url中指定的數據庫進行連接的驅動程序為止。driver的方法connect使用這個url來建立實際的連接。
用戶可繞過jdbc管理層直接調用driver方法。這在以下特殊情況下將很有用:當兩個驅動器可同時連接到數據庫中,而用戶需要明確地選用其中特定的驅動器。但一般情況下,讓drivermanager類處理打開連接這種事將更為簡單。
下述代碼顯示如何打開一個與位于url"jdbc:odbc:wombat"的數據庫的連接。所用的用戶標識符為"freely",口令為"ec":
string url = "jdbc:odbc:wombat";
connection con = drivermanager.getconnection(url, "freely", "ec");
2. 一般用法的url
由于url常引起混淆,我們將先對一般url作簡單說明,然后再討論jdbcurl。url(統一資源定位符)提供在internet上定位資源所需的信息??蓪⑺胂鬄橐粋€地址。url的第一部份指定了訪問信息所用的協議,后面總是跟著冒號。常用的協議有"ftp"(代表"文件傳輸協議")和"http"(代表"超文本傳輸協議")。如果協議是"file",表示資源是在某個本地文件系統上而非在internet上(下例用于表示我們所描述的部分;它并非url的組成部分)。
ftp://javasoft.com/docs/jdk-1_apidocs.zip
http://java.sun.com/products/jdk/currentrelease
file:/home/haroldw/docs/books/tutorial/summary.html
url的其余部份(冒號后面的)給出了數據資源所處位置的有關信息。如果協議是file,則url的其余部份是文件的路徑。對于ftp和http協議,url的其余部份標識了主機并可選地給出某個更詳盡的地址路徑。例如,以下是javasoft主頁的url。該url只標識了主機:http://java.sun.com。從該主頁開始瀏覽,就可以進到許多其它的網頁中,其中之一就是jdbc主頁。jdbc主頁的url更為具體,它具體表示為:
http://java.sun.com/products/jdbc
3. jdbc url
jdbc url提供了一種標識數據庫的方法,可以使相應的驅動程序能識別該數據庫并與之建立連接。實際上,驅動程序編程員將決定用什么jdbc url來標識特定的驅動程序。用戶不必關心如何來形成jdbc url;他們只須使用與所用的驅動程序一起提供的url即可。jdbc的作用是提供某些約定,驅動程序編程員在構造他們的jdbc url時應該遵循這些約定。
由于jdbc url要與各種不同的驅動程序一起使用,因此這些約定應非常靈活。首先,它們應允許不同的驅動程序使用不同的方案來命名數據庫。例如,odbc子協議允許(但并不是要求)url含有屬性值。
其次,jdbc url應允許驅動程序編程員將一切所需的信息編入其中。這樣就可以讓要與給定數據庫對話的applet打開數據庫連接,而無須要求用戶去做任何系統管理工作。
最后,jdbc url應允許某種程度的間接性。也就是說,jdbc url可指向邏輯主機或數據庫名,而這種邏輯主機或數據庫名將由網絡命名系統動態地轉換為實際的名稱。這可以使系統管理員不必將特定主機聲明為jdbc名稱的一部份。網絡命名服務(例如dns、nis和dce)有多種,而對于使用哪種命名服務并無限制。
jdbc url的標準語法如下所示。它由三部分組成,各部分間用冒號分隔:
jdbc:<子協遙荊海甲用疲?br> jdbc url的三個部分可分解如下:
?。?)jdbc協議:jdbc url中的協議總是jdbc。
(2)<子協議>:驅動程序名或數據庫連接機制(這種機制可由一個或多個驅動程序支持)的名稱。子協議名的典型示例是"odbc",該名稱是為用于指定odbc風格的數據資源名稱的url專門保留的。例如,為了通過jdbc-odbc橋來訪問某個數據庫,可以用如下所示的url:jdbc:odbc:book。本例中,子協議為"odbc",子名稱"book"是本地odbc數據資源。如果要用網絡命名服務(這樣jdbc url中的數據庫名稱不必是實際名稱),則命名服務可以作為子協議。例如,可用如下所示的url:jdbc:dcenaming:accounts。本例中,該url指定了本地dce命名服務應該將數據庫名稱"accounts"解析為更為具體的可用于連接真實數據庫的名稱。
(3)<子名稱>:種標識數據庫的方法。子名稱可以依不同的子協議而變化。它還可以有子名稱的子名稱(含有驅動程序編程員所選的任何內部語法)。使用子名稱的目的是為定位數據庫提供足夠的信息。前例中,因為odbc將提供其余部份的信息,因此用"book"就已足夠。然而,位于遠程服務器上的數據庫需要更多的信息。例如,如果數據庫是通過internet來訪問的,則在jdbc url中應將網絡地址作為子名稱的一部份包括進去,且必須遵循如下所示的標準url命名約定://主機名:端口/子協議。
假設"dbnet"是個用于將某個主機連接到internet上的協議,則jdbc url應為:jdbc:dbnet://wombat:356/fred。
4. "odbc"子協議
子協議odbc是一種特殊情況。它是為用于指定odbc風格的數據資源名稱的url而保留的,并具有下列特性:允許在子名稱(數據資源名稱)后面指定任意多個屬性值。odbc子協議的完整語法為:
jdbc:odbc:<數據資源名稱>[;<屬性名>=<屬性值>],因此,以下都是合法的jdbc:odbc名稱:
jdbc:odbc:qeor7
jdbc:odbc:wombat
jdbc:odbc:wombat;cachesize=20;extensioncase=lower
jdbc:odbc:qeora;uid=kgh;pwd=fooey
5. 注冊子協議
驅動程序編程員可保留某個名稱以將之用作jdbc url的子協議名。當drivermanager類將此名稱加到已注冊的驅動程序清單中時,為之保留該名稱的驅動程序應能識別該名稱并與它所標識的數據庫建立連接。例如,odbc是為jdbc-odbc橋而保留的。假設有個miracle公司,它可能會將"miracle"注冊為連接到其miracle dbms上的jdbc驅動程序的子協議,從而使其他人都無法使用這個名稱。
javasoft目前作為非正式代理負責注冊jdbc子協議名稱。要注冊某個子協議名稱,請發送電子郵件到下述地址:[email protected]。
6. 發送sql語句
連接一旦建立,就可用來向它所涉及的數據庫傳送sql語句。jdbc對可被發送的sql語句類型不加任何限制。這就提供了很大的靈活性,即允許使用特定的數據庫語句或甚至于非sql語句。然而,它要求用戶自己負責確保所涉及的數據庫可以處理所發送的sql語句,否則將自食其果。例如,如果某個應用程序試圖向不支持儲存程序的dbms發送儲存程序調用,就會失敗并將拋出異常。jdbc要求驅動程序應至少能提供ansi sql-2 entry level功能才可算是符合jdbc標準tm的。這意味著用戶至少可信賴這一標準級別的功能。
jdbc提供了三個類,用于向數據庫發送sql語句。connection接口中的三個方法可用于創建這些類的實例。下面列出這些類及其創建方法:
?。?)statement:由方法createstatement所創建。statement對象用于發送簡單的sql語句。
?。?)preparedstatement:由方法preparestatement所創建。preparedstatement對象用于發送帶有一個或多個輸入參數(in參數)的sql語句。preparedstatement擁有一組方法,用于設置in參數的值。執行語句時,這些in參數將被送到數據庫中。preparedstatement的實例擴展了statement,因此它們都包括了statement的方法。preparedstatement對象有可能比statement對象的效率更高,因為它已被預編譯過并存放在那以供將來使用。
(3)callablestatement:由方法preparecall所創建。callablestatement對象用于執行sql儲存程序─一組可通過名稱來調用(就象函數的調用那樣)的sql語句。callablestatement對象從preparedstatement中繼承了用于處理in參數的方法,而且還增加了用于處理out參數和inout參數的方法。
不過通常來說createstatement方法用于簡單的sql語句(不帶參數)、preparestatement方法用于帶一個或多個in參數的sql語句或經常被執行的簡單sql語句,而preparecall方法用于調用已儲存過程。
7. 事務
事務由一個或多個這樣的語句組成:這些語句已被執行、完成并被提交或還原。當調用方法commit或rollback時,當前事務即告就結束,另一個事務隨即開始。缺省情況下,新連接將處于自動提交模式。也就是說,當執行完語句后,將自動對那個語句調用commit方法。這種情況下,由于每個語句都是被單獨提交的,因此一個事務只由一個語句組成。如果禁用自動提交模式,事務將要等到commit或rollback方法被顯式調用時才結束,因此它將包括上一次調用commit或rollback方法以來所有執行過的語句。對于第二種情況,事務中的所有語句將作為組來提交或還原。
方法commit使sql語句對數據庫所做的任何更改成為永久性的,它還將釋放事務持有的全部鎖。而方法rollback將棄去那些更改。有時用戶在另一個更改生效前不想讓此更改生效。這可通過禁用自動提交并將兩個更新組合在一個事務中來達到。如果兩個更新都是成功,則調用commit方法,從而使兩個更新結果成為永久性的;如果其中之一或兩個更新都失敗了,則調用rollback方法,以將值恢復為進行更新之前的值。
大多數jdbc驅動程序都支持事務。事實上,符合jdbc的驅動程序必須支持事務。databasemetadata給出的信息描述dbms所提供的事務支持水平。
8. 事務隔離級別
如果dbms支持事務處理,它必須有某種途徑來管理兩個事務同時對一個數據庫進行操作時可能發生的沖突。用戶可指定事務隔離級別,以指明dbms應該花多大精力來解決潛在沖突。例如,當事務更改了某個值而第二個事務卻在該更改被提交或還原前讀取該值時該怎么辦。
假設第一個事務被還原后,第二個事務所讀取的更改值將是無效的,那么是否可允許這種沖突?jdbc用戶可用以下代碼來指示dbms允許在值被提交前讀取該值("dirty讀取"),其中con是當前連接:
con.settransactionisolation(transaction_read_uncommitted);
事務隔離級別越高,為避免沖突所花的精力也就越多。connection接口定義了五級,其中最低級別指定了根本就不支持事務,而最高級別則指定當事務在對某個數據庫進行操作時,任何其它事務不得對那個事務正在讀取的數據進行任何更改。通常,隔離級別越高,應用程序執行的速度也就越慢(由于用于鎖定的資源耗費增加了,而用戶間的并發操作減少了)。在決定采用什么隔離級別時,開發人員必須在性能需求和數據一致性需求之間進行權衡。當然,實際所能支持的級別取決于所涉及的dbms的功能。
當創建connection對象時,其事務隔離級別取決于驅動程序,但通常是所涉及的數據庫的缺省值。用戶可通過調用setisolationlevel方法來更改事務隔離級別。新的級別將在該連接過程的剩余時間內生效。要想只改變一個事務的事務隔離級別,必須在該事務開始前進行設置,并在該事務結束后進行復位。我們不提倡在事務的中途對事務隔離級別進行更改,因為這將立即觸發commit方法的調用,使在此之前所作的任何更改變成永久性的。