一個(gè)簡(jiǎn)單的 JDBC 包裝器一種簡(jiǎn)單程序的快速數(shù)據(jù)訪(fǎng)問(wèn)解決方案 ![]() |
![]() |
![]() |
級(jí)別: 初級(jí) Greg Travis (mito@panix.com), 自由程序員 2001 年 8 月 04 日 JDBC 提供了一種強(qiáng)大、全面的接口用來(lái)從 Java 程序訪(fǎng)問(wèn)數(shù)據(jù)庫(kù)。對(duì)于較小的項(xiàng)目來(lái)說(shuō),使用 JDBC 似乎是理所當(dāng)然的,它使一些程序員避免了一起使用數(shù)據(jù)庫(kù)。本文描述了一種簡(jiǎn)單的包裝器庫(kù),它讓使用簡(jiǎn)單的數(shù)據(jù)庫(kù)易如反掌。您會(huì)發(fā)現(xiàn)您已經(jīng)開(kāi)始想在編寫(xiě)的每一個(gè)程序中都使用 JDBC。 事情發(fā)生得很突然。您正在修改一個(gè)程序,您原以為它是個(gè)小程序,不料竟發(fā)現(xiàn)它已經(jīng)迅速增長(zhǎng)成為一個(gè)龐大的東西 ― 一個(gè) 項(xiàng)目― 而現(xiàn)在您已到了需要保存一些數(shù)據(jù)的時(shí)候了。 問(wèn)題是,您并不是有意讓程序發(fā)展到這種程度的。 您只是不由自主地做了一小部分修改。您并沒(méi)有真正準(zhǔn)備要存儲(chǔ)或裝入。而且,您的程序是個(gè) applet,而 applet 是無(wú)法存儲(chǔ)或裝入的。 可以存儲(chǔ)或裝入它們嗎? 實(shí)際上,JDBC API 允許任何 Java 程序 ― 甚至是 applet ― 連接到關(guān)系型數(shù)據(jù)庫(kù)(RDBMS)上。 不幸的是,JDBC 對(duì)您的小程序來(lái)說(shuō)可能有一點(diǎn)頭重腳輕了。畢竟,如果您希望做的只是存儲(chǔ)一點(diǎn)點(diǎn)數(shù)據(jù)的話(huà),RDBMS 是一個(gè)強(qiáng)大、復(fù)雜的系統(tǒng)。 在本文中,我們將分析一個(gè)簡(jiǎn)單的使用 JDBC 的抽象層。對(duì)于簡(jiǎn)單的應(yīng)用程序來(lái)說(shuō),它可以讓您只用幾行代碼就實(shí)現(xiàn)存儲(chǔ)和裝入結(jié)構(gòu)化數(shù)據(jù)。它不會(huì)處理復(fù)雜的 RDBMS 使用,但那正是我們要避免的,不是嗎? JDBC 使用起來(lái)可能是一個(gè)復(fù)雜的 API。它不僅必須支持整個(gè)強(qiáng)大的 SQL 標(biāo)準(zhǔn),還必須很好地隱藏不同數(shù)據(jù)庫(kù)引擎之間的區(qū)別。 JDBC 的復(fù)雜還在于關(guān)系型數(shù)據(jù)庫(kù)是基于 SQL 構(gòu)建的,而 SQL 是要給人用的,而不是給程序用的。直接使用 JDBC 有點(diǎn)象同時(shí)用兩種語(yǔ)言編程。 雖然 JDBC 的這些方面并不是什么壞事,但它們確實(shí)與我們的目標(biāo) ― 快速地存儲(chǔ)少量數(shù)據(jù)相沖突。
我們將創(chuàng)建一個(gè)簡(jiǎn)單的抽象層,讓您不必顧慮所有繁瑣的細(xì)節(jié)問(wèn)題來(lái)直接使用 JDBC。如果您早已熟悉 JDBC 或關(guān)系型數(shù)據(jù)庫(kù)了,那您一眼看到我們的類(lèi)列表應(yīng)該是很熟悉的:
我們這里不是在作任何實(shí)質(zhì)性的事情;我們的數(shù)據(jù)模型本質(zhì)上和關(guān)系型模型是一樣的,但去掉了煩人的細(xì)節(jié)(同時(shí)去掉了強(qiáng)大的功能)。每一個(gè)類(lèi)映射到一個(gè)基本的 RDBMS 概念上,同時(shí)也映射到一個(gè) JDBC 類(lèi)上。就是這種映射讓我們的 API 可以在保持易用性的同時(shí)保留它的相關(guān)特性。 這種 API 的設(shè)計(jì)是基于對(duì)我們的數(shù)據(jù)存儲(chǔ)需要的設(shè)想。如果您發(fā)現(xiàn)自己的程序需要一點(diǎn)不同的地方,您可以隨意地改變這種抽象以適應(yīng)您的情況。 這些類(lèi)可以被認(rèn)為是一種簡(jiǎn)化您工作的模式,而不是一成不變的規(guī)則。 如果您不熟悉 SQL 或者 RDBMS 技術(shù),不必害怕。 下面的四節(jié)中,每一節(jié)都會(huì)幫助您熟悉我們的一個(gè)類(lèi),還有這些類(lèi)映射到的 RDBMS 功能。 當(dāng)使用 JDBC 與數(shù)據(jù)庫(kù)建立連接時(shí),您必須告訴 JDBC 在何處可以找到實(shí)際的數(shù)據(jù)。 因?yàn)椴煌臄?shù)據(jù)庫(kù)引擎有不同的訪(fǎng)問(wèn)方法和描述這些方法的不同語(yǔ)法,所以有不止一種方法來(lái)指定數(shù)據(jù)源。 在 JDBC 中,統(tǒng)一資源標(biāo)識(shí)符(Uniform Resource Identifier,URI)字符串是用來(lái)指定數(shù)據(jù)源的,而這個(gè)字符串的結(jié)構(gòu)是依賴(lài)于數(shù)據(jù)庫(kù)的。
下面是如何創(chuàng)建一個(gè)
構(gòu)造函數(shù)的第一個(gè)參數(shù)是數(shù)據(jù)源的 URI。 在這個(gè)示例中,我使用了 PostgreSQL數(shù)據(jù)庫(kù)引擎,而且在本機(jī)上訪(fǎng)問(wèn)了一個(gè)名為 mito 的數(shù)據(jù)庫(kù)。 另外,我指定我的用戶(hù)名 mito 和一個(gè)空的密碼分別作為第二個(gè)和第三個(gè)參數(shù)。 一旦您創(chuàng)建了 我們?cè)?API 中對(duì)簡(jiǎn)化的一個(gè)設(shè)想就是,當(dāng)您從表的一行讀取數(shù)據(jù)時(shí),您會(huì)得到整行的數(shù)據(jù)。換句話(huà)說(shuō),表的一行是作為讀寫(xiě)單獨(dú)一塊數(shù)據(jù)的最小單位。這并不十分有效,但效率不是我們方法中所首要考慮的。
創(chuàng)建
注意,我們已經(jīng)指定了我們只需要那些‘id’值設(shè)定為‘101’的行。通過(guò)使用
在這種情況下,返回的值是一個(gè) 在接下來(lái)的兩節(jié)里,我們將討論 在我們的抽象中, 一旦您有了一個(gè) L清單 1. 從 Row 中獲取值
還要注意的是 清單 2. 迭代整個(gè) Row
當(dāng)然,您還可以改變 記住有一些查詢(xún)可以返回多個(gè) 清單 3. 迭代整個(gè) RowSet
現(xiàn)在我們已經(jīng)看過(guò)了所有的類(lèi),讓我們來(lái)看一個(gè)完整的示例吧。在清單 4 中,我們將抽取出符合特定條件的一套記錄,然后打印出它們的值。 清單 4. 一個(gè)讀取數(shù)據(jù)的完整示例
如此容易!在下一節(jié)中,我們將看看怎樣向數(shù)據(jù)庫(kù)寫(xiě)入數(shù)據(jù)。
正如前面所提到的,使用我們的 API 讀寫(xiě)數(shù)據(jù)是以整個(gè) 行為單位的。為了向數(shù)據(jù)庫(kù)寫(xiě)入數(shù)據(jù),您必須創(chuàng)建(或修改) 向數(shù)據(jù)庫(kù)寫(xiě)入數(shù)據(jù)是通過(guò)使用
這兩種變體分別對(duì)應(yīng)于 SQL 中的 在第一個(gè)變體中,寫(xiě)一行意味著將一個(gè)全新的行插入表中。 在第二個(gè)變體中,寫(xiě)一行意味著修改一個(gè)現(xiàn)有的行。 讓我們來(lái)看看每種方法的一個(gè)示例。 插入一個(gè)新行很簡(jiǎn)單,因?yàn)槟槐刂付ㄒ薷牡男校ㄒ恍谢蚨嘈校D皇呛?jiǎn)單地把行插入:
您可以重新創(chuàng)建一個(gè) 清單 5. 重新創(chuàng)建一個(gè) Row
或者,您可以修改一個(gè)以前曾經(jīng)從數(shù)據(jù)庫(kù)中讀取的一個(gè)現(xiàn)有的行,如清單 6 所示。 清單 6. 修改現(xiàn)有的 Row
雖然通常是在插入時(shí)重新創(chuàng)建 正如前面的部分提到的,對(duì)于您如何 創(chuàng)建用來(lái)更新的 為了詳細(xì)描述這一點(diǎn),我們將使用一個(gè)示例(在該例子中我們讀出一個(gè)員工的姓名),改變這個(gè)名字,然后將更改后的結(jié)果寫(xiě)回?cái)?shù)據(jù)庫(kù),如清單 7 所示。 清單 7. 通過(guò)修改 Row 進(jìn)行更新
注意我們必須在調(diào)用 注意,這個(gè)調(diào)用將更新 所有符合條件的行,而不是其中的一行。
在本文中,我們初步認(rèn)識(shí)了一種通過(guò) JDBC 包提供一種簡(jiǎn)化的通往關(guān)系型數(shù)據(jù)庫(kù)接口的 API。這種抽象保留了 JDBC 接口的很多基本關(guān)系型功能,但對(duì)其進(jìn)行了簡(jiǎn)化,從而讓使用非常地方便。這種簡(jiǎn)化是以效率為代價(jià)的,但當(dāng)目標(biāo)是簡(jiǎn)單性時(shí),這并不是一個(gè)令人驚奇的結(jié)果。
|