java開發(fā)技術(shù)第17章對數(shù)據(jù)庫編程_第1頁
java開發(fā)技術(shù)第17章對數(shù)據(jù)庫編程_第2頁
java開發(fā)技術(shù)第17章對數(shù)據(jù)庫編程_第3頁
java開發(fā)技術(shù)第17章對數(shù)據(jù)庫編程_第4頁
java開發(fā)技術(shù)第17章對數(shù)據(jù)庫編程_第5頁
已閱讀5頁,還剩26頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、第 17 章Java 對數(shù)據(jù)庫編程本章介紹如何使用 Java 類庫中的類來編寫數(shù)據(jù)庫應(yīng)用程序。一般的數(shù)據(jù)庫應(yīng)用程序分為客戶端和服務(wù)器端兩個(gè)部分。Java 的設(shè)計(jì)意圖是將它用于服務(wù)器端,而將客戶端交給其他語言編寫的工具去處理。所以 Java 與 Delphi、VB 的一個(gè)重要區(qū)別是,它不提供可視化的數(shù)據(jù)庫感應(yīng)控件,因而編寫客戶端時(shí)如果采用 Java 作為開發(fā)工具會(huì)有比較多的編程工作。17.1Java 對數(shù)據(jù)庫的連接無論何種工具,要處理數(shù)據(jù)庫必須做的第一件事情就是對數(shù)據(jù)進(jìn)行連接。Java 提供了多種連接方式,這都是通過 JDBC 來進(jìn)行的。本節(jié)將介紹 JDBC 的使用。17.1.1JDBC 的基本

2、概念JDBC 是 Java 數(shù)據(jù)庫連接(Java Database Connectivity)的簡寫,是一組用于連接數(shù)據(jù)庫以及執(zhí)行 SQL 語句的 API。它允許用戶從 JAVA 程序中據(jù)庫,也允許用戶其他的表格數(shù)據(jù)源,如 Excel 表格。任何支持 SQL 的關(guān)系型數(shù)JDBC 最大的特點(diǎn)是無論是何種數(shù)據(jù)庫,對于 Java 程序員而言,它的工作方式完全相同。JDBC 為許多不同的數(shù)據(jù)庫連接模塊的前端提供了接不同的數(shù)據(jù)庫而煩惱了。的接口,這樣就不用為連17.1.2JDBC 的工作方式JDBC 功能強(qiáng)大,但使用簡單。無論連接何種數(shù)據(jù)庫,只要做好下列步驟即可:與數(shù)據(jù)源建立連接,包括數(shù)據(jù)庫和電子表格。

3、通過 DriverManager 類建立與數(shù)據(jù)源的連接,這個(gè)連接將作為一個(gè)數(shù)據(jù)操作的起點(diǎn),同時(shí)也是連接會(huì)話事務(wù)操作的基礎(chǔ)。向數(shù)據(jù)庫發(fā)送 SQL 命令。通過 Sement 或者 PreparedSement 類向數(shù)據(jù)源發(fā)送 SQL 命令。在命令發(fā)送后,調(diào)用類中相應(yīng)的 excute 方法來執(zhí)行 SQL 命令。處理數(shù)據(jù)源返回的結(jié)果。數(shù)據(jù)庫處理了 SQL 命令后,將返回處理結(jié)果。對于 DDL 和 DML 操作,將返回被修Java 開發(fā)技術(shù)大全改的數(shù)量。對于查詢將返回一個(gè)ResultSet 結(jié)果集,程序接著遍歷這個(gè)結(jié)果集執(zhí)行想要的操作就行了。17.1.3JDBC 驅(qū)動(dòng)連接要與數(shù)據(jù)源連接,需要所連數(shù)據(jù)源的

4、驅(qū)動(dòng)程序。JDBC 有四種連接方式:JDBC-ODBC 橋接方式、本地 API部分Java 驅(qū)動(dòng)方式、JDBC-Net 純Java驅(qū)動(dòng)方式和本地協(xié)議純 Java 驅(qū)動(dòng)方式。下面分別介紹這些連接方式。1JDBC-ODBC橋加上ODBC驅(qū)動(dòng)程序圖 17.1ODBC 配置窗口ODBC 是 Windows上使用最廣泛的標(biāo)準(zhǔn)連接驅(qū)動(dòng)。所有能在Windows 上運(yùn)行的數(shù)據(jù)庫系統(tǒng)都提供了自己的 ODBC 驅(qū)動(dòng)。通過這種方式,能所有的Windows 上的數(shù)據(jù)庫。但是它的效率稍低,而且本地機(jī)器上需要安裝對應(yīng)的 ODBC 驅(qū)動(dòng)。下面演示了如何在本地機(jī)器上配置 ODBC 數(shù)據(jù):打開 ODBC 配置窗口。在控制面板中

5、找到 OBDC 配置的圖標(biāo)。如果是工具”中,如果是 Windows 2000,該圖標(biāo)就在控制面板中。找到圖標(biāo)后,雙擊它,出現(xiàn)如圖 17.1 所示的窗口。添加用戶數(shù)據(jù)源(DSN)。單擊圖 17.1 中的“添加”按鈕,出現(xiàn)如圖17.2 所示的窗口。在其中選擇要添加的WindowsXP,該圖標(biāo)在“管理圖 17.2添加用戶數(shù)據(jù)源數(shù)據(jù)源的類型。這里選擇的是 Acs。(3)為數(shù)據(jù)源添加屬性。這一步是為數(shù)據(jù)源添加一些屬性,其中最重要的是數(shù)據(jù)源的名稱,稍后 JDBC 要通過它來連接數(shù)據(jù)庫文件。單擊圖17.2 中的“完成”按鈕,出現(xiàn)如圖 17.3所示的窗口。圖 17.3為數(shù)據(jù)源添加屬性662第 17 章 Jav

6、a 對數(shù)據(jù)庫編程這里將數(shù)據(jù)源的名稱命名為“forStudy”,請記住該名稱,后面編程要用到。然后單擊“選擇”按鈕,會(huì)出現(xiàn)一個(gè)一般的文件選擇框,在其中選擇第 16 章創(chuàng)建的ple.mdb 文件即可。Exam-完成后,單擊“確定”按鈕,回到圖 17.1 所示界面上,會(huì)看到多出了一個(gè)用戶數(shù)據(jù)源,名稱為“forStudy”,表示配置成功。2本地API部分Java驅(qū)動(dòng)程序這種連接方式如圖 17.4 所示。驅(qū)動(dòng)程序使用本地API與數(shù)據(jù)源系統(tǒng)通信,使用 Java 方法調(diào)用執(zhí)行數(shù)據(jù)操作的 API函數(shù)。這就要求驅(qū)動(dòng)程序要與應(yīng)用程序一起駐留在客戶層上,并直接與數(shù)據(jù)庫服務(wù)器進(jìn)行通圖 17.4 本地 API 連接方式

7、信。因此,它要求客戶機(jī)上有一些二進(jìn)制代碼。這種方法速度比 JDBC-ODBC 更快,但它必須使用本地代碼,而且各個(gè)廠商提供的本地接口在驅(qū)動(dòng)中不一致,編程時(shí)需要查找廠商提供冊。這種驅(qū)動(dòng)連接方式最大的弱點(diǎn)是需要把開發(fā)商數(shù)據(jù)庫加載到每一臺(tái)客戶機(jī)上,因此它不能應(yīng)用于ernet。而且驅(qū)動(dòng)程序使用的是 Java Nativeerface,由于該接口在 JVM 的不同開發(fā)商之間沒有得到一致的實(shí)現(xiàn),所以它在間的移植性能也不是很好。3JDBC-Net純Java驅(qū)動(dòng)程序這種連接方式的驅(qū)動(dòng)程序采用一種三層化方法,JDBC 數(shù)據(jù)庫請求憑借這種方法,被轉(zhuǎn)換成數(shù)據(jù)庫獨(dú)立的網(wǎng)絡(luò)協(xié)議,并轉(zhuǎn)發(fā)給中間層服務(wù)器。然后中間層服務(wù)器再

8、把該請求轉(zhuǎn)換成數(shù)據(jù)庫特定的本機(jī)連接接口,并把該請求傳遞給數(shù)據(jù)庫服務(wù)器。如果中間層服務(wù)器是用 Java 編寫成的,它可以使用前面介紹的兩種類型的 JDBC 驅(qū)動(dòng)程序來完成這些工作,這意味著它在體系結(jié)構(gòu)上是非常靈活的。總的體系結(jié)構(gòu)由三層組成:JDBC 客戶和驅(qū)動(dòng)程序、中間件以及數(shù)據(jù)庫。如圖 17.5 所示:圖 17.5 JDBC-Net 連接方式在這種連接方式中,小 JDBC 驅(qū)動(dòng)程序(通常只有幾百 KB)在客戶機(jī)上執(zhí)行,并通過網(wǎng)絡(luò)把 SQL 命令傳遞給 JDBC 服務(wù)器,然后接收來自服務(wù)器的數(shù)據(jù),并管理連接。這種方式考慮到了在 ernet 上的部署。這種方式的優(yōu)點(diǎn)是顯而易見的:在中間層上有一個(gè)組

9、件,所以無需客戶機(jī)上存在任何數(shù)據(jù)庫。663Java 開發(fā)技術(shù)大全它的可移植性能和查詢性能都非常好,可以供多個(gè)用戶并發(fā)操作數(shù)據(jù)庫。客戶端的 JDBC 驅(qū)動(dòng)程序非常小,加載迅速,適合在ernet 上部署。它為高速緩存之類的功能、加載平衡以及日志和審計(jì)之類的共計(jì)系統(tǒng)管理提供了支持。大多數(shù)的三層 Web 應(yīng)用程序都涉及到安全、般都提供了這些功能。以及,而這類驅(qū)動(dòng)程序一當(dāng)然,這種方式也有其缺點(diǎn):要求數(shù)據(jù)庫特定的編碼在中間層完成,這增加了中間層設(shè)計(jì)者的負(fù)擔(dān),整個(gè)開發(fā)周期比前面兩種方式要長。遍歷查詢結(jié)果集時(shí)要花費(fèi)比較長的時(shí)間,這是因?yàn)檫@些數(shù)據(jù)要經(jīng)歷服務(wù)器。4本地協(xié)議的純Java驅(qū)動(dòng)程序它允許從 Java 客

10、戶端直接調(diào)用連接到數(shù)據(jù)庫服務(wù)器。它是純粹的 Java 程序,不需要對客戶端進(jìn)行配置,只需要相應(yīng)的驅(qū)動(dòng)程序名稱即可,這全面體現(xiàn)了 Java 的跨性和安全性。不過,當(dāng)數(shù)據(jù)庫變成一個(gè)不同開發(fā)商產(chǎn)品時(shí)(盡管這種情形很少見,但不能完全排除),不能使用同一個(gè) JDBC 驅(qū)動(dòng)程序,需要替換該驅(qū)動(dòng)程序。這些驅(qū)動(dòng)程序把 JDBC 直接轉(zhuǎn)換成 DBMS 開發(fā)商提供的 Java 驅(qū)動(dòng)程序。這些驅(qū)動(dòng)程序多數(shù)只能從 DBMS 開發(fā)商那里才能得到,因?yàn)橹挥虚_發(fā)商才最了解它們自己的協(xié)議。整個(gè)連接方式如圖 17.6 所示。圖 17.6 本地協(xié)議連接方式這種方式的優(yōu)點(diǎn)是:它不必把數(shù)據(jù)庫請求轉(zhuǎn)換成 ODBC 或者傳遞給另外一個(gè)服

11、務(wù)器,所以性能一般都很高,比第一和第二種方式都更好。無需在客戶端或者服務(wù)器端安裝特殊,而且這些驅(qū)動(dòng)程序可以態(tài)。這種方式的缺點(diǎn)在于,程序員需要給每個(gè)數(shù)據(jù)庫使用不同的 JDBC 驅(qū)動(dòng)程序。相對而言,在 Windows種方式較多。式較多,在 Linux/Unix上使用第上使用第四17.1.4連接池進(jìn)行 JDBC 操作的第一步就是建立數(shù)據(jù)庫連接。但這個(gè)過程是比較消耗資源的,如果664第 17 章 Java 對數(shù)據(jù)庫編程每進(jìn)行一次數(shù)據(jù)庫操作就建立一次連接,那么消耗在此動(dòng)作上面的時(shí)間和資源,將大大影響程序的效率。為解決這一問題,JDBC 使用了“連接池”的概念。在連接池中,保存了若干已經(jīng)建立好的數(shù)據(jù)連接。

12、每次需要與數(shù)據(jù)源通信的時(shí)候,如果所需要的連接在連接池里,那么直接使用這些現(xiàn)成的數(shù)據(jù)連接即可,使得運(yùn)行速度大大提高。數(shù)據(jù)庫連接池運(yùn)行在服務(wù)器端,而且對應(yīng)用程序的編碼沒有任何影響。不過前提是,應(yīng)用程序必須通過 DataSource 對象(一個(gè)實(shí)現(xiàn) javax.sql.DataSource 接口的實(shí)例)的方式,代替原有通過 DriverManager 類來獲得數(shù)據(jù)庫連接的方式。一個(gè)實(shí)現(xiàn) javax.sql.DataSource 接口的類可以支持也可以不支持?jǐn)?shù)據(jù)庫連接池,但是兩者獲得數(shù)據(jù)庫連接的代碼基本是相同的。它的一般代碼如下:如果當(dāng)前 DataSource 不支持?jǐn)?shù)據(jù)庫連接池,應(yīng)用程序?qū)@得一個(gè)和

13、物理數(shù)據(jù)庫連接對應(yīng)的 Connection 對象。而如果當(dāng)前的 DataSource 對象支持?jǐn)?shù)據(jù)庫連接池,應(yīng)用程序?qū)⒆詣?dòng)獲得重用的數(shù)據(jù)庫連接,而不用創(chuàng)建新的數(shù)據(jù)庫連接。重用的數(shù)據(jù)庫連接和新建立連接的數(shù)據(jù)庫連接,使用上沒有任何不同。應(yīng)用程序可以通過重用的連接正常地連接數(shù)據(jù)庫,進(jìn)行 數(shù)據(jù)的操作,完成操作后應(yīng)顯式地調(diào)用close()關(guān)閉數(shù)據(jù)庫連接。當(dāng)關(guān)閉數(shù)據(jù)連接后,當(dāng)前使用的數(shù)據(jù)庫連接將不會(huì)被物理關(guān)閉,而是放回到數(shù)據(jù)庫連接池中進(jìn)行重用。不過對于數(shù)據(jù)庫應(yīng)用程序員而言,這個(gè)操作是透明的。在 JDBC3.0 規(guī)范中,提供一個(gè)支持?jǐn)?shù)據(jù)庫連接池的框架。這個(gè)框架僅僅規(guī)定了如何支持連接池的實(shí)現(xiàn),而連接池的具體實(shí)

14、現(xiàn),JDBC 3.0 規(guī)范并沒有做相關(guān)的規(guī)定。通過這個(gè)框架。可以讓不同角色的開發(fā)通過 JDBC3.0 規(guī)范可以知共同實(shí)現(xiàn)數(shù)據(jù)庫連接池。體數(shù)據(jù)庫連接池的實(shí)現(xiàn)可以分為 JDBC Driver 級(jí)和Application Server 級(jí)。在 JDBC Driver 級(jí)的實(shí)現(xiàn)中,任何相關(guān)的工作均由特定數(shù)據(jù)庫廠商的 JDBC Driver 的開發(fā)來具體實(shí)現(xiàn),即 JDBC Driver 既需要提供對數(shù)據(jù)庫連接池的支持,同時(shí)也必須對數(shù)據(jù)庫連接池進(jìn)行具體實(shí)現(xiàn)。而在 Application Server 級(jí)中數(shù)據(jù)庫連接池的實(shí)現(xiàn)中,特定數(shù)據(jù)庫廠商的JDBC Driver 開發(fā)和 Application Serv

15、er 開發(fā),共同實(shí)現(xiàn)數(shù)據(jù)庫連接池的實(shí)現(xiàn)(但是現(xiàn)在大多數(shù)Application Server 廠商實(shí)現(xiàn)的連接池的機(jī)制和規(guī)范中提到有差異),其中特定數(shù)據(jù)庫廠商的 JDBC Driver 提供數(shù)據(jù)庫連接池的支持,而特定的 Application Server 廠商提供數(shù)據(jù)庫連接池的具體實(shí)現(xiàn)。這些具體的實(shí)現(xiàn)是比較高級(jí)的內(nèi)容,限于本書的篇幅,不做深入的研究。17.1.5事務(wù)操作有時(shí)候需要對多個(gè)數(shù)據(jù)表進(jìn)行操作,只有對這幾個(gè)表的操作都成功時(shí),才能認(rèn)為整個(gè)操作完成,這樣的操作稱為“事務(wù)操作”。如果某一個(gè)步驟失敗,之前的各個(gè)操作都要取消,這種取消動(dòng)作被稱為“回滾(rollback)”。JDBC 中的事務(wù)操作是基

16、于同一個(gè)數(shù)據(jù)連接的,各個(gè)連接之間互相獨(dú)立。當(dāng)數(shù)據(jù)連接斷開后,一個(gè)事務(wù)就結(jié)束了。關(guān)于事務(wù)操作的方法,都位于接口 java.sql.Connection 中。665Context ctx = new InitialContext();DataSource ds = (DataSource) ctx.lookup(jdbc/openbase);Java 開發(fā)技術(shù)大全在 JDBC 中,事務(wù)操作默認(rèn)是自動(dòng)提交。也就是說,一條對數(shù)據(jù)庫的更新表達(dá)式代表一項(xiàng)事務(wù)操作,操作成功后,系統(tǒng)將自動(dòng)調(diào)用commit()來提交,否則將調(diào)用 rollback()來回滾。同時(shí),程序還可以通過調(diào)用mit(false)來自動(dòng)提交

17、。之后就可以把多個(gè)數(shù)據(jù)庫操作的表達(dá)式作為一個(gè)事務(wù),在操作完成后調(diào)用 commit()來進(jìn)行整體提交,倘若其中一個(gè)表達(dá)式操作失敗,都不會(huì)執(zhí)行到 commit(),并且將產(chǎn)生相應(yīng)的異常。此時(shí),就可以在異常捕獲時(shí)調(diào)用 rollback()進(jìn)行回滾。這樣做可以保持多次更新操作后,相關(guān)數(shù)據(jù)的一致性。下面是程序片段:讀者現(xiàn)在不必完全弄懂這段代碼的含義,等到看完了本節(jié)后面的內(nèi)容,再回過來看這段代碼,就會(huì)完全明白每條語句的作用。JDBC API 支持事務(wù)對數(shù)據(jù)庫的加鎖,并且提供了 5 種操作支持,2 種加鎖密度。5 種支持如下。sicsicTRANTRANION_NONE:事務(wù)操作和加鎖。MITTED:允許臟

18、數(shù)據(jù)讀寫(dirty reads)、重復(fù)讀寫(repeatable reads)和影象讀寫(phantom reads)sicTRMITTED:臟數(shù)據(jù)讀寫、允許重復(fù)讀寫和影象讀寫。sicTRANION_REPEATABLE_READ:臟數(shù)據(jù)讀寫和重復(fù)讀寫,允許影象讀寫。sicTRANION_SERIALIZABLE:臟數(shù)據(jù)讀寫、重復(fù)讀寫和允許影象讀寫。其中幾個(gè)術(shù)語解釋如下。臟數(shù)據(jù)讀寫(dirty reads):當(dāng)一個(gè)事務(wù)修改了某一數(shù)據(jù)行的值而未提交時(shí),另一事務(wù)了此行值。倘若前一事務(wù)發(fā)生了回滾,則后一事務(wù)將得到一個(gè)無效的值(臟數(shù)據(jù))。666try conn = DriverManager.get

19、Connection(jdbc:odbc:forStudy,) mit(false);/自動(dòng)提交,設(shè)置回滾點(diǎn)stmt = conn.createSement();stmt.executeUpdate(“alter table ”);/數(shù)據(jù)庫更新操作 1 stmt.executeUpdate(“inserto table ”); /數(shù)據(jù)庫更新操作 2mit();/事務(wù)提交catch(Exception ex) ex.prStackTrace(); try conn.rollback();/操作不成功則回滾catch(Exception e) e.prStackTrace();第 17 章 Jav

20、a 對數(shù)據(jù)庫編程重復(fù)讀寫(repeatable reads):當(dāng)一個(gè)事務(wù)在某一數(shù)據(jù)行時(shí),另一事務(wù)同時(shí)在修改此數(shù)據(jù)行。則前一事務(wù)在重復(fù)此行時(shí),將得到一個(gè)不一致的值。影象讀寫(phantomreads):當(dāng)一個(gè)事務(wù)在某一表中進(jìn)行數(shù)據(jù)查詢時(shí),另一事務(wù)恰好了滿足了查詢條件的數(shù)據(jù)行。則前一事務(wù)在重復(fù)滿足條件的值時(shí),將得到一個(gè)額外的“影象”值。JDBC 根據(jù)數(shù)據(jù)庫提供的默認(rèn)值來設(shè)置事務(wù)支持及其加鎖,它有兩種加鎖密度:分別是表加鎖和行加鎖。在上述事務(wù)操作中,最后一項(xiàng)就是表加鎖,而第 3、4 項(xiàng)則是行加鎖。用程序設(shè)置加鎖的方法如下:Settranionisolation(level);也可以用下面的方法來查看

21、數(shù)據(jù)庫的當(dāng)前設(shè)置:注意:某些數(shù)據(jù)庫(如 oracle)中,數(shù)據(jù)庫驅(qū)動(dòng)對事務(wù)處理的默認(rèn)值是 TRANION_NONE,即不支持事務(wù)操作,所以需要在程序中手動(dòng)進(jìn)行設(shè)置。在進(jìn)行手動(dòng)設(shè)置時(shí),數(shù)據(jù)庫及其驅(qū)動(dòng)程序必須要支持相應(yīng)的事務(wù)操作操作才行。上述設(shè)置隨著加鎖密度的增加,其事務(wù)的獨(dú)立性隨之增加,更能有效地防止事務(wù)操作之間的。同時(shí),增加了加鎖的開銷,降低了用戶之間數(shù)據(jù)庫的并發(fā)性,程序的運(yùn)行效率也會(huì)隨之降低。因此程序員必須平衡程序運(yùn)行效率和數(shù)據(jù)一致性之間的。一般來說,對于只涉及到數(shù)據(jù)庫的查詢操作時(shí),可以采用 TRAN MITTED 方式;對于數(shù)據(jù)查詢遠(yuǎn)多于更新的操作,可以采用MITTED 方式;對于更新操作

22、較多的, 可以采用ION_READ_TRANTRANION_ION_REPEATABLE_READ;在數(shù)據(jù)一致性要求更高的場合再考慮最后一項(xiàng),由于涉及到表加鎖,因此會(huì)對程序運(yùn)行效率產(chǎn)生較大的影響。17.2Java 對數(shù)據(jù)庫的操作連接上數(shù)據(jù)庫之后,就可以對數(shù)據(jù)庫中的數(shù)據(jù)進(jìn)行操作了。無論何種語言、何種數(shù)據(jù)庫,也無論多么復(fù)雜的系統(tǒng),對數(shù)據(jù)庫的操作都不外乎 5 種基本操作:增、刪、改、查找和排序。在 Java 中,這些操作都是通過 SQL 語言來實(shí)現(xiàn)的。17.2.1常用接口及類要操作數(shù)據(jù)庫,多數(shù)需要通過下面的類以及接口來實(shí)現(xiàn)(本節(jié)的后面將通過一些例子來介紹這些類和接口的使用)。(1)DriverMan

23、ager 類DriverManager 類是 JDBC 的管理層,作用于用戶和驅(qū)動(dòng)程序之間。它可用的驅(qū)動(dòng)667getTranionIsolation();Java 開發(fā)技術(shù)大全程序,并在數(shù)據(jù)庫和相應(yīng)驅(qū)動(dòng)程序之間建立連接。另外,DriverManager 類也處理諸如驅(qū)動(dòng)程序登錄時(shí)間限制,及登錄和消息的顯示等事務(wù)。對于簡單的應(yīng)用程序,一般程序員需要在此類中直接使用的唯一方法是:DriverManager.getConnection()正如名稱所示,該方法將建立與數(shù)據(jù)庫的連接。JDBC 允許用戶調(diào)用DriverManager的方法 getDriver()、getDrivers()和 registe

24、rDriver()。但多數(shù)情況下,DriverManager 類自己管理建立連接的細(xì)節(jié)為上策。(2)Connection 接口該類對應(yīng)于數(shù)據(jù)庫連接對象,是 JDBC 操作的起點(diǎn),同時(shí)也是一個(gè) JDBC 事務(wù)的起點(diǎn),封裝了對數(shù)據(jù)庫連接的操作。一般情況下,Connetction 對象是由 DriverManager.getConn-ection()方法來得到的,程序只需要獲取該方法返回的一個(gè)指向 Connection 對象的,就可以對數(shù)據(jù)庫進(jìn)行操作。Connection 的方法比較多,但多數(shù)情況下,程序員只需要用到下面的兩個(gè)方法。Sement createSement():創(chuàng)建一個(gè) Sement

25、對象,并返回該對象將用于執(zhí)行具體的 SQL 命令。void close():關(guān)閉數(shù)據(jù)庫連接,(3)Sement 接口資源。這是執(zhí)行 SQL 命令的主要容器,它一次只能執(zhí)行一條 SQL 命令。它通過三個(gè)不同的方法來執(zhí)行 SQL 命令:ResultSet executeQuery(String sql):執(zhí)行 sql 命令,返回一個(gè)結(jié)果集合。通常用于執(zhí)行 SELECT 命令。executeUpdate(String sql):執(zhí)行 sql 命令,返回操作成功的于執(zhí)行 INSERT、UPDATE 或 DELETE 命令。execute(String sql):執(zhí)行 sql 命令,返回執(zhí)行結(jié)果的標(biāo)志。

26、如果值為 true,表示返回了一個(gè)結(jié)果集,需要用 getResultSet()方法獲取這個(gè)結(jié)果集,也可以使用getMoreResults() 獲取子結(jié)果集。如果為 false,表示沒有結(jié)果集,只需要調(diào)用條數(shù)。通常用getUpdateCount()方法獲取更新的條數(shù)。程序員需要根據(jù)執(zhí)行令來選擇合適的執(zhí)行方法。PreparedSement 接口與 Sement 類似,但它對 SQL 命令進(jìn)行預(yù)編譯,對于需要多次執(zhí)行的 SQL 語句而言,可以提高執(zhí)行效率。作為 Sement 的子接口,它不僅擁有 Sement 的所有方法,還增加了一套方法,通過使用一個(gè)稱為“占位符”的輸入?yún)?shù),程序員可以方便地將程序

27、中的變量轉(zhuǎn)換成為 SQL 語句中的變量,并降低出錯(cuò)的可能性。ResultSet 接口它用來接受 SQL 語句執(zhí)行后的結(jié)果,程序員可以通過 next()、previous()等方法來結(jié)果集中的任意一條。同時(shí)它還提供了大量輔助方法,方便中的各個(gè)字段。關(guān)于這個(gè)接口,將在 17.2.7 中詳細(xì)介紹。668第 17 章 Java 對數(shù)據(jù)庫編程17.2.2建立數(shù)據(jù)庫連接前面介紹過,建立數(shù)據(jù)庫連接有 4 種方式,這里以 Windows 系統(tǒng)下常用的JDBC-ODBC連接為例來講解。為連接到某個(gè)數(shù)據(jù)庫,首先要建立一個(gè) JDBC-ODBC 橋接器,它將 JDBC 操作轉(zhuǎn)換成ODBC 操作來完成。這需要使用sun

28、.jdbc.odbc 包和 java.lang 包中的類來實(shí)現(xiàn)。(1)加載 ODBC 驅(qū)動(dòng),使用下面的方法:該方法是一個(gè)靜態(tài)方法,可以直接使用。同時(shí),它還可能拋出異常,所以需要寫在try-catch 語句塊中。注意,這里是加載 ODBC 驅(qū)動(dòng),無論是何種數(shù)據(jù)庫,該驅(qū)動(dòng)程序是不變的。如果不是采用 JDBC-ODBC 橋,而采用其他的 Java 驅(qū)動(dòng),就需要加載對應(yīng)的驅(qū)動(dòng)程序。例如,是,加載驅(qū)動(dòng)程序的代碼是:Class.forName(.glt.mm.Driver);如果是 DB2,則加載方式為:其余的數(shù)據(jù)庫,請查閱數(shù)據(jù)庫幫助。(2)建立連接加載了驅(qū)動(dòng)程序后,就可以建立連接了。這需要使用 java

29、.sql 中的 Connection 類來聲明一個(gè)對象,再使用類 DriverManager 的靜態(tài)方法 getConnection 創(chuàng)建連接對象。該方法的如下:第一個(gè)參數(shù)是指定要連接的數(shù)據(jù)庫名稱,該數(shù)據(jù)庫既可以是本地的,也可以是的。后兩個(gè)參數(shù)分別是用戶名和,如果數(shù)據(jù)庫沒有該項(xiàng)設(shè)置,可以為空。如果使用 ODBC 驅(qū)動(dòng),則要寫成這個(gè)樣子:注意:這里是數(shù)據(jù)源而非數(shù)據(jù)庫名稱。如果是非 ODBC 驅(qū)動(dòng),例如名稱”。,則要寫成:“jdbc:/數(shù)據(jù)庫主機(jī)名/數(shù)據(jù)庫【例 17.1】 使用 JDBC-ODBC 橋來連接一個(gè) Acs 數(shù)據(jù)庫。該數(shù)據(jù)庫的名稱為Exle,在 ODBC 數(shù)據(jù)源中的名稱為“forStu

30、dy”,用戶和口為空。這就是第 16 章建立的數(shù)據(jù)庫,以及 17.1 節(jié)配置的 ODBC 數(shù)據(jù)源。/連接數(shù)據(jù)庫示例程序段,程序17.1-669tryClass.forName(sun.jdbc.odbc.JdbcOdbcDriver);/加載數(shù)據(jù)庫驅(qū)動(dòng)jdbc:odbc:數(shù)據(jù)源名字sic Connection getConnection(String url, String user, String password);Class.forName(COM.ibm.db2.jdbc.app.DB2Driver);Class.forName(sun.jdbc.odbc.JdbcOdbcDriver

31、);Java 開發(fā)技術(shù)大全17.2.3關(guān)閉數(shù)據(jù)庫連接調(diào)用 Connection 的 close()方法可以關(guān)閉數(shù)據(jù)庫連接。但在實(shí)際應(yīng)用中,可能會(huì)出現(xiàn)各種異常情況,程序就不會(huì)按照正常流程運(yùn)行,就可能出現(xiàn) close()方法沒有被調(diào)用的情況,而程序即便終止了運(yùn)行,仍然會(huì)占用數(shù)據(jù)庫的連接數(shù)量,這就是“連接泄漏”。當(dāng)數(shù)據(jù)庫的連接數(shù)量達(dá)到極限后,就會(huì)導(dǎo)致數(shù)據(jù)庫不再響應(yīng)用戶請求,甚至停止等,這是必須要避免的。所以,一般將 close 寫在 try-catch-finally 的 finally 語句中,保證即便發(fā)生異常,數(shù)據(jù)庫也一定會(huì)關(guān)閉?!纠?17.2】 關(guān)閉數(shù)據(jù)庫連接示例。/關(guān)閉數(shù)據(jù)庫示例程序段,程序

32、17.2-17.2.4添加新數(shù)據(jù)獲得連接后,程序就可以操作數(shù)據(jù)庫了,先來看如何添加數(shù)據(jù)。這需要使用 SQL 語句,一般將 SQL 語句存放在一個(gè) Sement 對象中,然后執(zhí)行該對象的 executeUpdate()方法就可以了?!纠?17.3】 向數(shù)據(jù)庫中添加新數(shù)據(jù)。Exle 中有一張表名為 student,它具有 code、name、sex、address、例如,在數(shù)據(jù)庫room、6 個(gè)字段(如果您的數(shù)據(jù)庫中該表的字段不是這個(gè)樣子,請將其設(shè)置成這樣 6 個(gè)字段),希望添加一條:(30,如下:,男,湖南湘潭,N-408,8293456),程序代碼670tryClass.forName(sun

33、.jdbc.odbc.JdbcOdbcDriver);Connection con=DriverManager.getConnection(jdbc:odbc:forStudy,);catch(ClaotFoundException e)catch(SQLException e)finally /在這里關(guān)閉數(shù)據(jù)庫 if(con!=null)tryif(!con.isClosed()con.close(); /關(guān)閉數(shù)據(jù)庫連接catch(SQLException el) el.prStackTrace();/end try-catch/end if /end try-catch-finallyCo

34、nnection con=DriverManager.getConnection(jdbc:odbc:forStudy,);/這里是 ODBC 數(shù)據(jù)源名稱catch(ClaotFoundException e)catch(SQLException e)第 17 章Java 對數(shù)據(jù)庫編程/程序名 insertData.java,程序17.3-執(zhí)行該程序后,可用 Acs 打開 student 表來查看數(shù)據(jù)是否成功。上面的程序?qū)崿F(xiàn)比較簡單,但沒有多大的實(shí)際意義,因?yàn)樵趯?shí)際運(yùn)行中,需要的數(shù)據(jù)通常都是由用戶輸入的,是一些變量。而將變量組配成一條 SQL 語句是一件很容易出錯(cuò)的事。例變量: code=30

35、, name=room=N-408, =8293456那么像這樣組配:, sex= 男, address= 湖南湘潭,是肯定錯(cuò)誤的,被代入到 SQL 語句中去的是“code”、“name”這樣的變量名,而非它所的字符串。所以應(yīng)該寫成這個(gè)樣子:這樣寫,才會(huì)將這些變量本身的值代入到SQL 語句中。一個(gè)可以接受用戶輸入的程序,如下所示:/程序名 insertData.java,程序17.4-671sqlString=inserto student values(+code+,+name+,+sex+, +address+,+ room + , + ,);sqlString=inserto stude

36、nt values(code,name,sex,address, room,);/本程序測試數(shù)據(jù)import java.sql.*;public class insertData public sic void main(String args) Connection con=null;Sement stmt;/要執(zhí)行的 SQL 語句String sqlString=inserto student values(30, ,男,湖南湘潭,N-408,8293456);try/加載數(shù)據(jù)庫驅(qū)動(dòng) Class.forName(sun.jdbc.odbc.JdbcOdbcDriver);/連接數(shù)據(jù)庫con

37、=DriverManager.getConnection(jdbc:odbc:forStudy,); stmt=con.createSement();/執(zhí)行命令stmt.executeUpdate(sqlString); System.out.prln(成功);catch(Exception e) e.prStackTrace();finally trycon.close();catch(SQLException e) e.prStackTrace();Java 開發(fā)技術(shù)大全程序運(yùn)行截圖如圖 17.7 所示:672import java.sql.*; import java.io.*;publ

38、ic class insertData public sic void main(String args) Connection con=null;Sement stmt; String sqlString;String name,sex,address,code,room,; tryClass.forName(sun.jdbc.odbc.JdbcOdbcDriver); con=DriverManager.getConnection(jdbc:odbc:forStudy,); stmt=con.createSement();code=getInput(請輸入:);name=getInput(

39、請輸入:); sex=getInput(請輸入:); address=getInput(請輸入地址:); room=getInput(請輸入寢室:);=getInput(請輸入:);/拼裝 SQL 字符串sqlString=inserto student values( +code +, + name + ,+ sex + , + address + ,+ room + , + );stmt.executeUpdate(sqlString); System.out.prln(成功);catch(Exception e) e.prStackTrace();finally trycon.close

40、();catch(SQLException e) e.prStackTrace();/接收用戶輸入public sic String getInput(String msg) String result=null;try/創(chuàng)建用戶輸入流BufferedReader in=new BufferedReader(new InputStreamReader (System.in) );System.out.pr(msg); result=in.readLine();catch(IOException e) e.prStackTrace();return result;第 17 章 Java 對數(shù)據(jù)庫

41、編程圖 17.7 程序運(yùn)行截圖從程序 17.4 中可以看出,將程序中的變量還原成 SQL 命令可以使用的字符串是件很容易出錯(cuò)的工作,如果字符串本身中還含有雙引號(hào)或單引號(hào),轉(zhuǎn)換就會(huì)變得更為 。即便是非常熟練的程序員,也很可能在這里犯錯(cuò)。所以,Java 又提供了一個(gè) PreparedS ement類,該類一個(gè)重要的作用就是提供了一個(gè)“占位符”,可以方便程序員進(jìn)行轉(zhuǎn)換工作。上面的例子可以改成:然后用下面的程序:注意上面的第一個(gè)占位符的設(shè)置。在 Acs 中,數(shù)值型字段其實(shí)仍然是以字符串來存儲(chǔ)的,所以即便 code 是整型數(shù)據(jù),仍然可以使用 setString 這種方式來為數(shù)值型字段賦值。而對于其他的大

42、型數(shù)據(jù)庫,是嚴(yán)格區(qū)分等來賦值。整個(gè)程序如程序 17.5 所示:/程序名 insertData.java,程序、long、short 等類型的,就必須要用set或setLong17.5-673import java.sql.*; import java.io.*;public class insertData public sic void main(String args) Connection con=null;PreparedSement ps; String sqlString;String name,sex,address,code,room,; tryClass.forName(su

43、n.jdbc.odbc.JdbcOdbcDriver); con=DriverManager.getConnection(jdbc:odbc:forStudy,); code=getInput(請輸入:);name=getInput(請輸入:);sex=getInput(請輸入:); address=getInput(請輸入地址:); room=getInput(請輸入寢室:);=getInput(請輸入:);PreparedSement ps=con.prepareSement(sqlString); ps.setString(1,code);/替換第一個(gè)占位符ps.setString(4,

44、address);/替換第四個(gè)占位符 ps.executeUpdate();sqlString=inserto student values(?,?,?,?); /?就是占位符Java 開發(fā)技術(shù)大全這個(gè)程序的運(yùn)行情況和程序 17.4 是完全一樣的。17.2.5刪除數(shù)據(jù)刪除數(shù)據(jù)很簡單,只要執(zhí)行 SQL 語句中的刪除命令 delete 即可。delete 命令本身比較簡單,只是仍然需要 Java 中字符串的組配與 SQL 命令字符串之間的差異。下面是一個(gè)簡單的例子。【例 17.4】 從數(shù)據(jù)庫中刪除。/程序名 deleteData.java,程序17.6-674import java.sql.*;

45、import java.io.*;public class deleteData public sic void main(String args) Connection con=null;sqlString=inserto student values(?,?,?,?,?,?); ps=con.prepareSement(sqlString); ps.setString(1,code); /替換第一個(gè)占位符ps.setString(2,name); ps.setString(3,sex); ps.setString(4,address); ps.setString(5,room);ps.se

46、tString(6,); ps.executeUpdate(); /執(zhí)行 SQL 命令 System.out.prln(成功);catch(Exception e) e.prStackTrace();finally trycon.close();catch(SQLException e) e.prStackTrace();public sic String getInput(String msg) String result=null;tryBufferedReader in=new BufferedReader(new InputStreamReader (System.in);System

47、.out.pr(msg); result=in.readLine();catch(IOException e) e.prStackTrace();return result;第 17 章Java 對數(shù)據(jù)庫編程17.2.6修改數(shù)據(jù)使用 SQL 語句中 update 命令就可以修改數(shù)據(jù),該命令第 16 章已經(jīng)介紹過。下面是個(gè)簡單的例子,將所有為“男”的改成“女”?!纠?17.5】 修改數(shù)據(jù)示例。/程序名 updateData.java,程序17.7-675import java.sql.*; import java.io.*;public clapdateData public sic void

48、main(String args) Connection con=null;Sement stmt; String sqlString; String code;k;tryClass.forName(sun.jdbc.odbc.JdbcOdbcDriver); con=DriverManager.getConnection(jdbc:odbc:forStudy,); code=getInput(請輸入要?jiǎng)h除的:);sqlString=delete from student where code=+code+; stmt=con.createSement();/執(zhí)行刪除命令,并獲取成功執(zhí)行的數(shù)k

49、=stmt.executeUpdate(sqlString); System.out.prln(刪除了+k+條);catch(Exception e) e.prStackTrace();finally trycon.close();catch(SQLException e) e.prStackTrace();public sic String getInput(String msg) String result=null;tryBufferedReader in=new BufferedReader(new InputStreamReader (System.in);System.out.pr

50、(msg); result=in.readLine();catch(IOException e) e.prStackTrace();return result;Java 開發(fā)技術(shù)大全17.2.7查詢數(shù)據(jù)利用 SELECT 語句查詢得到結(jié)果后,會(huì)將結(jié)果放在一個(gè) ResultSet 集中,遍歷這個(gè)集合就可以做任何需要的操作。ResultSet 是由 Java 提供的一個(gè)非常有用的類,每當(dāng)查詢語句執(zhí)行完成后,就會(huì)返回一個(gè)查詢結(jié)果的集合給它。可以將它想像成一張表,只包含那些查詢符合條件的行和列。這一個(gè)游標(biāo)(cursors),可以把它想象成一根指針,它始終指向集中的某一行,所有對集的操作,默認(rèn)都是對這根

51、游標(biāo)所指向的的操作。因此 ResultSet 提供了大量的方法供程序員來管理這根游標(biāo)。ResultSet 的方法非常多,表 17.1 列出了其中一些常用的方法。表 17.1 ResultSet的常用方法676方法說明absolute(row)將游標(biāo)移動(dòng)到指定行位置(絕對值)void afterLast()將游標(biāo)移動(dòng)到結(jié)果集的最后一條的后面void before()將游標(biāo)移動(dòng)到結(jié)果集的第一條的前面void cancelRowUpdates()取消本行數(shù)據(jù)的更新void clearWarnings()清除本對象的所有警告void close()立即關(guān)閉與結(jié)果集連接的數(shù)據(jù)庫并JDBC資源void d

52、eleteRow()從結(jié)果集以及數(shù)據(jù)表中刪除游標(biāo)所指向的findColumn(String columnName)查找結(jié)果集中是否有給定的字段名稱()將游標(biāo)移動(dòng)到結(jié)果集的第一條處Sement stmt; String sqlString;k;tryClass.forName(sun.jdbc.odbc.JdbcOdbcDriver); con=DriverManager.getConnection(jdbc:odbc:forStudy,);/SQL 命令字符串sqlString=update student set sex=女 where sex=男; stmt=con.createSemen

53、t();/執(zhí)行 SQL 命令k=stmt.executeUpdate(sqlString); System.out.prln(修改了+k+條);catch(Exception e) e.prStackTrace();finally trycon.close();catch(SQLException e) e.prStackTrace();第 17 章Java 對數(shù)據(jù)庫編程續(xù)表677方法說明BigDecimal getBigDecimal(columnIndex)將游標(biāo)指向的中由columnIndex所確定的字段轉(zhuǎn)換成為BigDecimal數(shù)據(jù)返回get(columnIndex)將游標(biāo)指向的中由

54、columnIndex所確定的字段轉(zhuǎn)換成為數(shù)據(jù)返回byte getByte(columnIndex)將游標(biāo)指向的中由columnIndex所確定的字段轉(zhuǎn)換成為byte數(shù)據(jù)返回String getCursorName()獲取當(dāng)前使用的游標(biāo)名稱Date getDate(columnIndex)將游標(biāo)指向的中由columnIndex所確定的字段轉(zhuǎn)換成為Date數(shù)據(jù)返回double getDouble(columnIndex)將游標(biāo)指向的中由columnIndex所確定的字段轉(zhuǎn)換成為double數(shù)據(jù)返回get(columnIndex)將游標(biāo)指向的中由columnIndex所確定的字段轉(zhuǎn)換成為 數(shù)據(jù)返回

55、long getLong(columnIndex)將游標(biāo)指向的中由columnIndex所確定的字段轉(zhuǎn)換成為long數(shù)據(jù)返回getRow()獲取游標(biāo)所指向的行數(shù)short getShort(String columnName)將游標(biāo)指向的中由columnIndex所確定的字段轉(zhuǎn)換成為short數(shù)據(jù)返回S ement getS ement()返回與結(jié)果集相關(guān)聯(lián)的S ement對象String getString(columnIndex)將游標(biāo)指向的中由columnIndex所確定的字段轉(zhuǎn)換成為String數(shù)據(jù)返回getType()返回結(jié)果集對象的類型,它的類型是下列三個(gè)之一: ResultSet

56、.TYPE_FORWARD_ONLY; ResultSet.TYPE_SCROLL_INSENSITIVE; ResultSet.TYPE_SCROLL_SENSITIVEvoid insertRow()將準(zhǔn)備的到結(jié)果集以及對應(yīng)的表中isAfterLast()測試游標(biāo)是否在最后一條的后面isBefore()測試游標(biāo)是否在第一條的前面is()測試游標(biāo)是否在第一條處isLast()測試游標(biāo)是否在最后一條處last()將游標(biāo)移動(dòng)到最后一條處void moveToCurrentRow()將游標(biāo)移動(dòng)到前面下來的位置處,通常是當(dāng)前位置。如果處于狀態(tài),此方法無效void moveToInsertRow()將

57、游標(biāo)移動(dòng)到要的位置next()將游標(biāo)向后移動(dòng)一行previous()將游標(biāo)向前移動(dòng)一行void refreshRow()刷新游標(biāo)所指向的值relative(rows)將游標(biāo)移動(dòng)到相對于當(dāng)前位置差rows行的位置rowDeleted()測試行是否已被刪除rowInserted()測試行是否已入rowUpdated()測試行是否已被更新void updateByte(columnIndex, byte x)將當(dāng)前的columnIndex字段用x的值來取代Java 開發(fā)技術(shù)大全續(xù)表下面的例子中先用 SQL 查詢獲取一個(gè)結(jié)果集,然后遍歷這個(gè)結(jié)果集,將其中的出到屏幕?!纠?17.6】 查詢數(shù)據(jù)示例。輸/

58、程序名 queryData.java,程序17.8-678import java.sql.*; import java.io.*; public class queryDatapublic sic void main(String args) Connection con=null;Sement stmt; ResultSet rs;String name,sex,address,code; tryClass.forName(sun.jdbc.odbc.JdbcOdbcDriver); con=DriverManager.getConnection(jdbc:odbc:forStudy,);

59、stmt=con.createSement();/執(zhí)行查詢命令,并獲取返回的結(jié)果集rs=stmt.executeQuery(select * from student);/下面開始遍歷結(jié)果集 while(rs.next() /游標(biāo)向后移動(dòng)name=rs.getString(name); /獲取 name 字段的內(nèi)容 sex=rs.getString(sex);/獲取 sex 字段的內(nèi)容 address=rs.getString(address); code=rs.getString(code);System.out.prln(name + + sex+ +address+ +code);cat

60、ch(Exception e) e.prStackTrace();finally trycon.close();catch(SQLException e) e.prStackTrace();/try end/method end/class end方法說明void updateDate(columnIndex, Date x)將當(dāng)前的columnIndex字段用x的值來取代void updateDouble(columnIndex, double x)將當(dāng)前的columnIndex字段用x的值來取代void update(columnIndex,x)將當(dāng)前的columnIndex字段用x的值來

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論