JSP學習——全面解析JDBC(2)
來源:互聯網
上載者:User
js 如何建立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"(代表"超文字傳輸通訊協定 (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的三個部分可分解如下:
(1)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子協議名稱。要註冊某個子協議名稱,請寄送電子郵件到下述地址:jdbc@wombat.eng.sun.com。
6. 發送SQL語句
串連一旦建立,就可用來向它所涉及的資料庫傳送SQL語句。JDBC對可被發送的SQL語句類型不加任何限制。這就提供了很大的靈活性,即允許使用特定的資料庫語句或甚至於非SQL語句。然而,它要求使用者自己負責確保所涉及的資料庫可以處理所發送的SQL語句,否則將自食其果。例如,如果某個應用程式試圖向不支援儲存程式的DBMS發送儲存程式調用,就會失敗並將拋出異常。JDBC要求驅動程式應至少能提供ANSI SQL-2 Entry Level功能才可算是符合JDBC標準TM的。這意味著使用者至少可信賴這一標準層級的功能。
JDBC提供了三個類,用於向資料庫發送SQL語句。Connection介面中的三個方法可用於建立這些類的執行個體。下面列出這些類及其建立方法:
(1)Statement:由方法createStatement所建立。Statement對象用於發送簡單的SQL語句。
(2)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方法的調用,使在此之前所作的任何更改變成永久性的。