Java開發(fā)綜合實(shí)戰(zhàn) 教案 項(xiàng)目十 訪問(wèn)數(shù)據(jù)庫(kù)_第1頁(yè)
Java開發(fā)綜合實(shí)戰(zhàn) 教案 項(xiàng)目十 訪問(wèn)數(shù)據(jù)庫(kù)_第2頁(yè)
Java開發(fā)綜合實(shí)戰(zhàn) 教案 項(xiàng)目十 訪問(wèn)數(shù)據(jù)庫(kù)_第3頁(yè)
Java開發(fā)綜合實(shí)戰(zhàn) 教案 項(xiàng)目十 訪問(wèn)數(shù)據(jù)庫(kù)_第4頁(yè)
Java開發(fā)綜合實(shí)戰(zhàn) 教案 項(xiàng)目十 訪問(wèn)數(shù)據(jù)庫(kù)_第5頁(yè)
已閱讀5頁(yè),還剩19頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

STYLEREFbt1a項(xiàng)目十STYLEREFbt1b訪問(wèn)數(shù)據(jù)庫(kù)項(xiàng)目十訪問(wèn)數(shù)據(jù)庫(kù)思政目標(biāo)找對(duì)學(xué)習(xí)方法,注重前后知識(shí)的遷移,能舉一反三。鼓勵(lì)應(yīng)用創(chuàng)新,引導(dǎo)學(xué)生融會(huì)貫通,增強(qiáng)實(shí)踐能力。技能目標(biāo)能夠利用常用的SQL語(yǔ)句查詢、更新、添加和刪除記錄。能夠使用JDBC操作數(shù)據(jù)庫(kù)中的數(shù)據(jù)。項(xiàng)目導(dǎo)讀在開發(fā)應(yīng)用程序的過(guò)程中,數(shù)據(jù)庫(kù)扮演著十分重要的角色,絕大多數(shù)的應(yīng)用都需要使用數(shù)據(jù)庫(kù)來(lái)存儲(chǔ)和管理數(shù)據(jù)。JAVA提供了專門用于操作數(shù)據(jù)庫(kù)的API,即JDBC(JavaDatabaseConnectivity,Java數(shù)據(jù)庫(kù)連接),可以很容易地訪問(wèn)不同的數(shù)據(jù)庫(kù),對(duì)數(shù)據(jù)庫(kù)中的記錄實(shí)現(xiàn)查詢、修改、刪除和添加等操作。Java開發(fā)綜合實(shí)戰(zhàn)任務(wù)1SQL語(yǔ)法基礎(chǔ)任務(wù)引入小白創(chuàng)建的進(jìn)銷存管理系統(tǒng)使用數(shù)組存儲(chǔ)商品信息,為便于后期的數(shù)據(jù)擴(kuò)容和管理,他決定利用數(shù)據(jù)庫(kù)存儲(chǔ)、管理商品數(shù)據(jù)。為熟悉數(shù)據(jù)查詢操作,他使用SQLServer創(chuàng)建了一個(gè)存儲(chǔ)學(xué)生成績(jī)的數(shù)據(jù)庫(kù)performance,并創(chuàng)建了一個(gè)成績(jī)表score、錄入了數(shù)據(jù)。如果他要查詢、更新、添加或刪除數(shù)據(jù)庫(kù)中的數(shù)據(jù),可以使用什么語(yǔ)句呢?知識(shí)準(zhǔn)備訪問(wèn)數(shù)據(jù)庫(kù)要使用SQL語(yǔ)句。SQL(StructuredQueryLanguage,結(jié)構(gòu)查詢語(yǔ)言)是一個(gè)用于與數(shù)據(jù)庫(kù)通信的數(shù)據(jù)庫(kù)語(yǔ)言,是關(guān)系數(shù)據(jù)庫(kù)管理系統(tǒng)的標(biāo)準(zhǔn)語(yǔ)言。SQL語(yǔ)句主要有以下3大類,每一類語(yǔ)言包含或多或少的語(yǔ)句,使用在不同的應(yīng)用程序中。數(shù)據(jù)定義語(yǔ)言(DDL):用于定義數(shù)據(jù)的結(jié)構(gòu),例如創(chuàng)建、修改或刪除數(shù)據(jù)庫(kù)或數(shù)據(jù)庫(kù)中的對(duì)象(如表、視圖、存儲(chǔ)過(guò)程、觸發(fā)器等)。數(shù)據(jù)操縱語(yǔ)言(DML):用于操作數(shù)據(jù)表中的數(shù)據(jù),主要包括數(shù)據(jù)的插入、刪除、更新、查找、過(guò)濾和排序等,是最常用的核心SQL語(yǔ)言。數(shù)據(jù)控制語(yǔ)言(DCL):用于分配數(shù)據(jù)庫(kù)用戶的權(quán)限。在一般的應(yīng)用程序中使用較多的是數(shù)據(jù)操縱語(yǔ)言,可以使用CRUD概括地表示對(duì)數(shù)據(jù)庫(kù)的常見操作,即表的創(chuàng)建(Create)、數(shù)據(jù)檢索(Retrieve)、數(shù)據(jù)更新(Update)和刪除(Delete)操作。SQL語(yǔ)言很復(fù)雜也很龐大,因篇幅所限,本節(jié)僅簡(jiǎn)要介紹常用的幾個(gè)數(shù)據(jù)操縱語(yǔ)句,更多的SQL語(yǔ)句讀者可以查閱相關(guān)資料。一、select語(yǔ)句該語(yǔ)句用于在數(shù)據(jù)表中檢索符合查詢條件的數(shù)據(jù)行,僅包含指定的字段。其語(yǔ)法格式如下:SELECT所選字段列表FROM數(shù)據(jù)表名[WHERE查詢條件表達(dá)式][ORDERBY字段名[ASC|DESC]如果要檢索數(shù)據(jù)表中的所有列,可以使用通配符(*)替代字段列表。ORDER子句用于將查詢結(jié)果集按照某個(gè)字段值進(jìn)行排序,關(guān)鍵字ASC表示升序,DESC表示降序。案例——查詢成績(jī)表SQLServer數(shù)據(jù)庫(kù)performance中的score表由一群學(xué)生的成績(jī)數(shù)據(jù)組成,每一行包含四個(gè)字段,即學(xué)生姓名、數(shù)學(xué)成績(jī)、語(yǔ)文成績(jī)和外語(yǔ)成績(jī),如圖10-1所示。圖10-1score表如果要查詢?cè)摫碇袛?shù)學(xué)成績(jī)?cè)?0及以上的學(xué)生名單及對(duì)應(yīng)的數(shù)學(xué)成績(jī),并將結(jié)果按降序排列,可以利用如下SQL語(yǔ)句:SELECTname,MathFROMscoreWHERE(Math>=90)ORDERBYMathDESC查詢的結(jié)果如圖10-2所示。圖10-2select命令查詢結(jié)果二、insert語(yǔ)句INSERT語(yǔ)句用于在一個(gè)表中插入單行或多行數(shù)據(jù),同時(shí)賦給每個(gè)列相應(yīng)的值,如果這個(gè)值支持它們定義的物理順序中的所有的值,則不需要字段名。其語(yǔ)法格式如下:INSERT[INTO]表名或視圖名[(字段列表)]VALUES(字段值列表)例如,下面的語(yǔ)句在表score中插入了學(xué)生Alex的成績(jī)記錄:INSERTINTOscore(name,Math,Chinese,English)VALUES('Alex',87,93,92)其中,字段列表可以省略。執(zhí)行上面的語(yǔ)句后,表score如圖10-3示。圖10-3插入記錄后的score表三、update語(yǔ)句UPDATE語(yǔ)句用于根據(jù)查詢條件更新數(shù)據(jù)表中的某些字段值。其語(yǔ)法格式如下:UPDATE數(shù)據(jù)表名SET字段名1=字段值1,字段名2=字段值2……WHERE條件表達(dá)式例如,使用以下語(yǔ)句,可以在表score中修改olivia的數(shù)學(xué)和英語(yǔ)成績(jī):UPDATEscoreSETMath=89,English=92WHERE(name='Olivia')注意:SQL語(yǔ)句中的字符串應(yīng)包含在單引號(hào)中。該語(yǔ)句執(zhí)行之后,表score如圖10-4所示。圖10-4更新記錄后的score表四、delete語(yǔ)句該語(yǔ)句用于在數(shù)據(jù)庫(kù)中刪除符合指定條件的數(shù)據(jù)行,其語(yǔ)法格式如下:DELETEFROM數(shù)據(jù)表名[WHERE條件表達(dá)式]如果有查詢條件,則刪除與查詢條件相符的數(shù)據(jù)行;如果沒有查詢條件,將刪除所有的記錄。例如,下面的語(yǔ)句刪除表score中語(yǔ)文成績(jī)小于90分的成績(jī)記錄:DELETEFROMscoreWHERE(Chinese<90)執(zhí)行上面的語(yǔ)句后,score表如圖10-5所示。圖10-5刪除記錄后的score表任務(wù)2使用JDBC訪問(wèn)數(shù)據(jù)庫(kù)任務(wù)引入小白掌握了常用的查詢語(yǔ)句后,想利用圖形用戶界面修改數(shù)據(jù)庫(kù)中的數(shù)據(jù),但是怎樣將數(shù)據(jù)庫(kù)與Java應(yīng)用程序關(guān)聯(lián)起來(lái)呢?他查看相關(guān)資料得知,JDBC為連接數(shù)據(jù)庫(kù)提供了統(tǒng)一的規(guī)范,決定采用JDBC訪問(wèn)數(shù)據(jù)庫(kù)。接下來(lái)該如何在系統(tǒng)中部署JDBC,連接數(shù)據(jù)庫(kù)呢?查詢數(shù)據(jù)后怎樣輸出滿足條件的數(shù)據(jù)記錄呢?知識(shí)準(zhǔn)備一、JDBC概述JDBC是一套用于執(zhí)行SQL語(yǔ)句的JavaAPI,提供了一套數(shù)據(jù)庫(kù)操作標(biāo)準(zhǔn),可以采用相同的API實(shí)現(xiàn)對(duì)多種關(guān)系型數(shù)據(jù)庫(kù)的統(tǒng)一操作,從而提高Java程序多數(shù)據(jù)庫(kù)的可移植性。簡(jiǎn)單來(lái)說(shuō),JDBC能完成下列三種功能:與一個(gè)數(shù)據(jù)庫(kù)建立連接向數(shù)據(jù)庫(kù)發(fā)送SQL語(yǔ)句處理數(shù)據(jù)庫(kù)返回的結(jié)果JDBC由兩層構(gòu)成:上層是JDBCAPI,負(fù)責(zé)在Java應(yīng)用程序和JDBC驅(qū)動(dòng)程序管理器之間進(jìn)行通信,發(fā)送程序中的SQL語(yǔ);下層是JDBC驅(qū)動(dòng)程序API,負(fù)責(zé)JDBC驅(qū)動(dòng)程序管理器與實(shí)際連接的數(shù)據(jù)庫(kù)的廠商驅(qū)動(dòng)程序和第三方驅(qū)動(dòng)程序之間進(jìn)行通信,返回查詢信息或者執(zhí)行規(guī)定的操作。如果要使用JDBC訪問(wèn)某種數(shù)據(jù)庫(kù)中的數(shù)據(jù),計(jì)算機(jī)上必須安裝有JDBC驅(qū)動(dòng)程序。二、部署JDBC驅(qū)動(dòng)程序JDBC針對(duì)每一個(gè)數(shù)據(jù)庫(kù)廠商都提供了一個(gè)JDBC驅(qū)動(dòng)程序。在連接到數(shù)據(jù)庫(kù)之前,必須首先在本地計(jì)算機(jī)上安裝數(shù)據(jù)庫(kù)和JDBC驅(qū)動(dòng)程序。不同版本的JDBC驅(qū)動(dòng)程序?qū)RE的要求也不相同,因此部署JDBC驅(qū)動(dòng)程序之前,要先選擇正確的JAR類庫(kù)文件。例如MicrosoftJDBCDriver10.2安裝包中包含三個(gè)JAR類庫(kù):mssql-jdbc-10.2.0.jre8.jar、mssql-jdbc-10.2.0.jre11.jar和mssql-jdbc-10.2.0.jre17.jar。其中,mssql-jdbc-10.2.0.jre11.jar需要Java運(yùn)行時(shí)環(huán)境(JRE)11.0,使用JRE10.0或更低版本會(huì)引發(fā)異常。mssql-jdbc-10.2.0.jre17.jar需要JavaRuntimeEnvironment(JRE)17.0,使用較低版本會(huì)引發(fā)異常。JDBC驅(qū)動(dòng)程序的具體系統(tǒng)要求可參見對(duì)應(yīng)數(shù)據(jù)庫(kù)的官網(wǎng)說(shuō)明。由于JDBC類庫(kù)文件不是JavaSDK的一部分,因此,在下載合適的類庫(kù)文件后,應(yīng)將jar類庫(kù)文件包含在用戶應(yīng)用程序的環(huán)境變量classpath中。如果使用JDBCDriver10.2,應(yīng)在classpath中包括mssql-jdbc-10.2.0.jre8.jar、mssql-jdbc-10.2.0.jre11.jar或mssql-jdbc-10.2.0.jre17.jar,如圖10-6所示。圖10-6設(shè)置變量CLASSPATH如果在IDE中運(yùn)行訪問(wèn)數(shù)據(jù)庫(kù)的Java項(xiàng)目,需要將JDBC數(shù)據(jù)庫(kù)驅(qū)動(dòng)包添加到當(dāng)前項(xiàng)目的構(gòu)建路徑中,步驟如下。(1)在Eclipse中右擊項(xiàng)目名,從彈出的快捷菜單中選擇BuildPath→ConfigureBuildPath...命令。(2)在打開的對(duì)話框左側(cè)窗格中選中“JavaBuildPath”節(jié)點(diǎn),然后在Libraries選項(xiàng)卡中選中Classpath,單擊AddLibrary...按鈕,如圖10-7所示。(3)在打開的AddLibrary對(duì)話框的庫(kù)列表框中選擇“UserLibrary”,然后單擊Next按鈕,在彈出的對(duì)話框中,依次單擊UserLibraries按鈕,New按鈕,新建一個(gè)用戶庫(kù)的名稱。(4)依次單擊OK按鈕和ApplyandClose按鈕關(guān)閉對(duì)話框。然后單擊AddExternalJARs按鈕,在打開的對(duì)話框中選擇與JRE匹配的JDBCJAR包文件(比如與JRE17匹配的mssql-jdbc-10.2.0.jre17.jar)。單擊“打開”按鈕關(guān)閉對(duì)話框,此時(shí)可以看到新建的用戶庫(kù)如圖10-8所示。圖10-7項(xiàng)目屬性對(duì)話框圖10-8創(chuàng)建的用戶庫(kù)(5)依次單擊ApplyandClose按鈕和Finish按鈕關(guān)閉對(duì)話框。此時(shí)在項(xiàng)目的屬性對(duì)話框中可以看到添加的類庫(kù)路徑,如圖10-9所示。圖10-9添加的類庫(kù)路徑(6)添加完成后,單擊ApplyandClose按鈕關(guān)閉對(duì)話框。三、連接數(shù)據(jù)庫(kù)使用JDBC數(shù)據(jù)庫(kù)驅(qū)動(dòng)方式和數(shù)據(jù)庫(kù)建立連接需要經(jīng)過(guò)兩個(gè)步驟:(1)注冊(cè)JDBC驅(qū)動(dòng)程序;(2)與指定數(shù)據(jù)庫(kù)建立連接。這些操作使用JDBC中的Driver接口、DriverManager類和Connection接口實(shí)現(xiàn)。1.注冊(cè)驅(qū)動(dòng)程序注冊(cè)驅(qū)動(dòng)程序就是將特定數(shù)據(jù)庫(kù)的驅(qū)動(dòng)程序類裝載到JVM。每種數(shù)據(jù)庫(kù)的驅(qū)動(dòng)程序都提供一個(gè)實(shí)現(xiàn)Driver接口的類,簡(jiǎn)稱Driver類,是應(yīng)用程序必須首先加載的類,用于向驅(qū)動(dòng)程序管理器(java.sql.DriverManager類)注冊(cè)該類的實(shí)例,以便驅(qū)動(dòng)程序管理器管理數(shù)據(jù)庫(kù)驅(qū)動(dòng)程序。在JDBCAPI4.0之前,通常使用java.lang.Class類的靜態(tài)方法forName(className)加載要連接的數(shù)據(jù)庫(kù)驅(qū)動(dòng)程序類,并將加載的類自動(dòng)向DriverManager類注冊(cè),參數(shù)為要加載的數(shù)據(jù)庫(kù)驅(qū)動(dòng)程序的完整類名。如果加載失敗,則拋出ClassNotFoundException異常。例如,下面的程序段可用于檢測(cè)SQLServer數(shù)據(jù)庫(kù)驅(qū)動(dòng)程序類是否成功加載。try{//加載JDBC驅(qū)動(dòng)器 Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");out.println("驅(qū)動(dòng)器類加載成功");}catch(ClassNotFoundExceptione){ out.println("加載驅(qū)動(dòng)器類時(shí)出現(xiàn)異常");}提示:在加載驅(qū)動(dòng)程序之前,應(yīng)確保驅(qū)動(dòng)程序已經(jīng)在Java編譯器的類路徑中,否則會(huì)拋出找不到相關(guān)類的異常信息。要在項(xiàng)目中添加數(shù)據(jù)庫(kù)驅(qū)動(dòng)程序,可以將下載的JDBC驅(qū)動(dòng)程序直接存放在Web服務(wù)目錄的WEB-INF/lib/目錄下。從JDBCAPI4.0開始,DriverManager.getConnection()方法得到了增強(qiáng),可自動(dòng)加載JDBC驅(qū)動(dòng)程序。因此,使用驅(qū)動(dòng)程序jar庫(kù)時(shí),應(yīng)用程序無(wú)需調(diào)用Class.forName方法注冊(cè)驅(qū)動(dòng)程序。當(dāng)前通過(guò)使用Class.forName方法加載驅(qū)動(dòng)程序的現(xiàn)有應(yīng)用程序仍可繼續(xù)工作,無(wú)需進(jìn)行修改。2.建立連接注冊(cè)數(shù)據(jù)庫(kù)驅(qū)動(dòng)程序后,JVM和數(shù)據(jù)庫(kù)之間還沒有直接聯(lián)系,需要調(diào)用DriverManager類的靜態(tài)方法getConnection()方法獲得一個(gè)數(shù)據(jù)庫(kù)連接對(duì)象,建立Java應(yīng)用程序與指定數(shù)據(jù)庫(kù)之間的聯(lián)系。建立數(shù)據(jù)庫(kù)連接對(duì)象的過(guò)程涉及兩個(gè)主要API:java.sql.DriverManager類和java.sql.Connection接口。DriverManager是JDBC用于管理驅(qū)動(dòng)程序的類,主要用于管理用戶程序與特定數(shù)據(jù)庫(kù)的連接。Connection接口類對(duì)象是應(yīng)用程序連接數(shù)據(jù)庫(kù)的連接對(duì)象,主要作用是調(diào)用createStatement()方法創(chuàng)建語(yǔ)句對(duì)象。DriverManager類有如下兩個(gè)用于建立連接的靜態(tài)方法:Connectionconn=DriverManager.getConnection(URL,user,password);Connectionconn=DriverManager.getConnection(URL);URL參數(shù)是每個(gè)JDBC驅(qū)動(dòng)程序?qū)S玫腏DBCURL,語(yǔ)法格式如下:jdbc:子協(xié)議:數(shù)據(jù)庫(kù)定位器子協(xié)議與JDBC驅(qū)動(dòng)程序有關(guān),根據(jù)實(shí)際的JDBC驅(qū)動(dòng)程序廠商而不同。提示:不同版本的SQLServer數(shù)據(jù)庫(kù)的子協(xié)議有所不同。SQLServer2005之前的版本為microsoft:sqlserver;而SQLServer2005及之后的版本子協(xié)議為sqlserver。數(shù)據(jù)庫(kù)定位器用于指定要與應(yīng)用程序進(jìn)行交互的數(shù)據(jù)庫(kù),根據(jù)驅(qū)動(dòng)程序的類型,可能包括主機(jī)名、端口和數(shù)據(jù)庫(kù)系統(tǒng)名。例如:連接SQLServer數(shù)據(jù)庫(kù)sample的URL為"jdbc:sqlserver://localhost:1433;DatabaseName=sample"。localhost(或127.0.0.1)表示本機(jī)地址,1433是SQLServer的默認(rèn)端口號(hào),sample是數(shù)據(jù)庫(kù)名稱。很多驅(qū)動(dòng)程序還接受在URL末尾附加參數(shù),如數(shù)據(jù)庫(kù)賬號(hào)的用戶名和密碼,此時(shí)采用getConnection()方法的第二種格式。例如:以下語(yǔ)句連接MySQL數(shù)據(jù)庫(kù)sample:Stringurl="jdbc:mysql://localhost:3306/sample?user=root&password=123";Connectionconn=DriverManager.getConnection(url);參數(shù)user和password分別為用戶登錄數(shù)據(jù)庫(kù)管理系統(tǒng)的用戶名及密碼。如果沒有設(shè)置用戶名和密碼,參數(shù)設(shè)置為空即可。由于getConnection()方法可能拋出SQLException異常,因此在程序中應(yīng)捕獲異常。例如,與SQLServer數(shù)據(jù)源student建立連接的語(yǔ)句如下:try{Stringurl="jdbc:sqlserver://localhost:1433;DatabaseName=student";Connectioncon=DriverManager.getConnection(url,"sa","123456");}catch(SQLExceptione){ //處理異常}注意:如果數(shù)據(jù)庫(kù)表的記錄包含漢字,在建立連接時(shí)應(yīng)在URL參數(shù)中附加一個(gè)characterEncoding參數(shù),值為utf-8或gb2312。四、操作數(shù)據(jù)庫(kù)與數(shù)據(jù)庫(kù)建立連接后,就可以使用JDBC提供的API與數(shù)據(jù)庫(kù)進(jìn)行交互。交互的主要方式是使用SQL語(yǔ)句,JDBC將標(biāo)準(zhǔn)的SQL語(yǔ)句發(fā)送給數(shù)據(jù)庫(kù),數(shù)據(jù)庫(kù)執(zhí)行指令并處理查詢結(jié)果,返回結(jié)果集。1.發(fā)送、執(zhí)行SQL指令向數(shù)據(jù)庫(kù)發(fā)送SQL指令需要使用Statement接口類對(duì)象聲明一個(gè)SQL語(yǔ)句,然后通過(guò)創(chuàng)建的數(shù)據(jù)庫(kù)連接對(duì)象調(diào)用方法createStatement()創(chuàng)建這個(gè)SQL語(yǔ)句對(duì)象,語(yǔ)法格式如下:try{ Statementsql=con.createStatement();}catch(SQLExceptione){//處理異常}Statement接口定義了執(zhí)行語(yǔ)句和獲取結(jié)果的基本方法,用于將不帶參數(shù)的簡(jiǎn)單SQL語(yǔ)句發(fā)送到數(shù)據(jù)庫(kù),并獲取指定SQL語(yǔ)句的執(zhí)行結(jié)果。Statement接口包含以下3種執(zhí)行SQL語(yǔ)句的方法。execute(Stringsql):可執(zhí)行任何SQL語(yǔ)句,返回結(jié)果為布爾值。如果值為true,表明有結(jié)果集,通常是執(zhí)行了select查詢語(yǔ)句;如果值為false,表明沒有結(jié)果集,通常是執(zhí)行了insert、delete、update等增刪改語(yǔ)句。executeQuery(Stringsql):通常執(zhí)行select查詢語(yǔ)句,返回單個(gè)ResultSet結(jié)果集。executeUpdate(Stringsql):常用于執(zhí)行DML和DDL語(yǔ)句,返回值為int型。執(zhí)行DML語(yǔ)句時(shí)返回受SQL語(yǔ)句影響的數(shù)據(jù)行數(shù);執(zhí)行DDL語(yǔ)句返回0。當(dāng)Connection對(duì)象處于默認(rèn)狀態(tài)時(shí),所有Statement對(duì)象都是自動(dòng)執(zhí)行的,也就是說(shuō),當(dāng)Statement語(yǔ)句對(duì)象執(zhí)行SQL語(yǔ)句時(shí),該SQL語(yǔ)句馬上提交數(shù)據(jù)庫(kù)并返回結(jié)果。如果將連接修改為手動(dòng)提交的事務(wù)模式,則只有執(zhí)行commit()方法時(shí),才會(huì)提交相應(yīng)的數(shù)據(jù)庫(kù)操作。Statement對(duì)象使用完畢后,最好使用close()方法將其關(guān)閉。如果要執(zhí)行動(dòng)態(tài)SQL語(yǔ)句,可使用PreparedStatement接口類對(duì)象,該接口繼承自Statement接口,具有Statement接口的所有方法。由于PreparedStatement實(shí)例對(duì)象保存有已被預(yù)編譯的SQL語(yǔ)句,因此執(zhí)行速度比Statement對(duì)象快。通過(guò)調(diào)用Connection接口對(duì)象的preparedStatement()方法可獲得PreparedStatement對(duì)象,語(yǔ)法格式如下:Connectionconn=DriverManager.getConnection(url,"user","password");PreparedStatementpstmt=conn.preparedStatement(Stringsql);從上面的語(yǔ)法格式可以看到,使用preparedStatement()方法創(chuàng)建PreparedStatement對(duì)象時(shí),需要SQL命令字符串作為參數(shù),以實(shí)現(xiàn)SQL命令預(yù)編譯。在SQL命令中可以包含一個(gè)或多個(gè)IN參數(shù),也可以使用“?”作為占位符。在調(diào)用executeQuery()或executeUpdate()方法之前,使用如表10-1所示的setXxx()方法為占位符賦值。表10-1PreparedStatement接口常用的方法方法說(shuō)明setInt(intindex,intk)將SQL命令中出現(xiàn)次序?yàn)閕ndex的參數(shù)設(shè)置為int值ksetFloat(intindex,floatk)將SQL命令中出現(xiàn)次序?yàn)閕ndex的參數(shù)設(shè)置為float值ksetLong(intindex,longk)將SQL命令中出現(xiàn)次序?yàn)閕ndex的參數(shù)設(shè)置為long值ksetDouble(intindex,doublek)將SQL命令中出現(xiàn)次序?yàn)閕ndex的參數(shù)設(shè)置為double值ksetDate(intindex,datek)將SQL命令中出現(xiàn)次序?yàn)閕ndex的參數(shù)設(shè)置為date值k續(xù)表方法說(shuō)明setString(intindex,Strings)將SQL命令中出現(xiàn)次序?yàn)閕ndex的參數(shù)設(shè)置為String值ssetNull(intindex,intsqlType)將SQL命令中出現(xiàn)次序?yàn)閕ndex的參數(shù)設(shè)置為SQLNULL例如,下面的程序段利用PreparedStatement對(duì)象在score表中插入一條記錄:try{//包含4個(gè)占位符的SQL命令Stringsql="insertintoscore(name,Math,Chinese,English)values(?,?,?,?)";//創(chuàng)建PreparedStatement對(duì)象pstmtPreparedStatementpstmt=conn.preparedStatement(sql); //為占位符賦值pstmt.setString(1,"Jeson"); //為name字段賦值pstmt.setInt(2,85); //為Math字段賦值pstmt.setInt(3,92); //為Chinese字段賦值pstmt.setInt(4,94); //為English字段賦值pstmt.executeUpdate(); //執(zhí)行插入操作}catch(IOExceptione){}2.返回結(jié)果集如果執(zhí)行的SQL語(yǔ)句是查詢語(yǔ)句,將返回一個(gè)ResultSet對(duì)象存放查詢結(jié)果。ResultSet對(duì)象由按字段組織的數(shù)據(jù)行構(gòu)成,并具有指向當(dāng)前數(shù)據(jù)行的游標(biāo)。當(dāng)獲得一個(gè)ResultSet時(shí),游標(biāo)指向第一行記錄之前的位置,一次只能看到一個(gè)數(shù)據(jù)行。通過(guò)next()方法可移動(dòng)到下一個(gè)數(shù)據(jù)行,沒有下一行時(shí)返回false。獲得一行數(shù)據(jù)后,ResultSet對(duì)象可以使用如表10-2所示的getXxx()方法獲得字段值,方法的參數(shù)可以是字段的位置索引或者是字段的名稱。表10-2獲取結(jié)果集字段值的常用方法方法說(shuō)明getInt(intcolumnIndex)或getInt(StringcolumnLabel)以int形式返回ResultSet對(duì)象當(dāng)前數(shù)據(jù)行指定列的值。如果列值為NULL,返回0getFloat(intcolumnIndex)或getFloat(StringcolumnLabel)以float形式返回ResultSet對(duì)象當(dāng)前數(shù)據(jù)行指定列的值。如果列值為NULL,返回0getDate(intcolumnIndex)或getDate(StringcolumnLabel)以date形式返回ResultSet對(duì)象當(dāng)前數(shù)據(jù)行指定列的值。如果列值為NULL,返回null

續(xù)表方法說(shuō)明getBoolean(intcolumnIndex)或getBoolean(StringcolumnLabel)以Boolean形式返回ResultSet對(duì)象當(dāng)前數(shù)據(jù)行指定列的值。如果列值為NULL,返回nullgetString(intcolumnIndex)或getString(StringcolumnLabel)以String形式返回ResultSet對(duì)象當(dāng)前數(shù)據(jù)行指定列的值。如果列值為NULL,返回null默認(rèn)情況下,ResultSet的游標(biāo)只能向下一行單向移動(dòng),如果要在結(jié)果集中向前移動(dòng)、或顯示結(jié)果集指定的某條記錄,則需要調(diào)用數(shù)據(jù)庫(kù)連接對(duì)象的createStatement(inttype,intconcurrency)方法創(chuàng)建一個(gè)Statement對(duì)象,然后執(zhí)行SQL語(yǔ)句返回一個(gè)可以滾動(dòng)的結(jié)果集。語(yǔ)法格式如下:Statementst=conn.createStatement(inttype,intconcurrency);ResultSetrs=st.executeQuery(Stringsql);其中,type的取值(如表10-3所示)決定滾動(dòng)方式;concurrency取值(如表10-4所示)決定是否可以用結(jié)果集更新數(shù)據(jù)庫(kù)。表10-3參數(shù)type的取值值含義ResultSet.TYPE_FORWORD_ONLY游標(biāo)只能向下移動(dòng)ResultSet.TYPE_SCROLL_INSENSITIVE游標(biāo)可以上下移動(dòng),數(shù)據(jù)庫(kù)變化時(shí),當(dāng)前結(jié)果集不變ResultSet.TYPE_SCROLL_SENSITIVE游標(biāo)可以上下移動(dòng),數(shù)據(jù)庫(kù)變化時(shí),當(dāng)前結(jié)果集同步改變表10-4參數(shù)concurrency的取值值含義ResultSet.CONCUR_READ_ONLY不能用結(jié)果集更新數(shù)據(jù)庫(kù)中的表ResultSet.CONCUR_UPDATETABLE能用結(jié)果集更新數(shù)據(jù)庫(kù)中的表創(chuàng)建可滾動(dòng)的結(jié)果集后,利用ResultSet接口提供的一些方法可以很方便地在結(jié)果集中移動(dòng)游標(biāo),如表10-5所示。表10-5移動(dòng)游標(biāo)的常用方法方法說(shuō)明first()將游標(biāo)移到結(jié)果集的第一行next()將游標(biāo)移到當(dāng)前數(shù)據(jù)行的下一行l(wèi)ast()將游標(biāo)移到結(jié)果集的最后一行beforeFirst()將游標(biāo)移動(dòng)到結(jié)果集的第一行之前beforeLast()將游標(biāo)移動(dòng)到結(jié)果集最后一行之后absolute(introw)將游標(biāo)移動(dòng)到參數(shù)row指定的行號(hào)。需要注意的是,如果row為負(fù)值,表示倒數(shù)的行數(shù),即absolute(-1)表示移動(dòng)到最后一行在結(jié)果集中移動(dòng)游標(biāo)后,使用getRow()方法可以獲取游標(biāo)所指行的行號(hào),如果結(jié)果集沒有行,則返回0。使用isFirst()和isLast()方法可以分別判斷游標(biāo)是否指向結(jié)果集的第一行和最后一行。注意:對(duì)數(shù)據(jù)庫(kù)進(jìn)行操作時(shí),返回的ResultSet對(duì)象與Connection對(duì)象是有緊密聯(lián)系的,如果使用close()方法關(guān)閉連接對(duì)象,ResultSet對(duì)象中的數(shù)據(jù)會(huì)即刻消失。因此,應(yīng)在數(shù)據(jù)庫(kù)操作結(jié)束后關(guān)閉數(shù)據(jù)庫(kù)連接,釋放資源,包括關(guān)閉ResultSet和Statement等資源。案例——修改學(xué)生成績(jī)表本案例利用圖形用戶界面修改SQLServer數(shù)據(jù)庫(kù)performance中的學(xué)生成績(jī)表score。成績(jī)表score的初始數(shù)據(jù)行如圖10-10所示。圖10-10初始數(shù)據(jù)表(1)在Eclipse中新建一個(gè)名為StudentQuery的Java項(xiàng)目。然后在項(xiàng)目中添加一個(gè)名為StudentList的類,創(chuàng)建用戶界面,為按鈕注冊(cè)監(jiān)聽器,監(jiān)聽ActiveEvent事件,并使用匿名內(nèi)部類訪問(wèn)數(shù)據(jù)庫(kù),處理按鈕的動(dòng)作事件。具體代碼如下:importjava.awt.Container;importjava.awt.event.ActionListener;importjava.awt.event.ActionEvent;importjava.sql.Connection;importjava.sql.DriverManager;importjava.sql.PreparedStatement;importjava.sql.ResultSet;importjava.sql.SQLException;importjavax.swing.JButton;importjavax.swing.JFrame;importjavax.swing.JOptionPane;importjavax.swing.JScrollPane;importjavax.swing.JTextArea;publicclassStudentListextendsJFrame{ privatestaticfinallongserialVersionUID=1L; //定義組件 privateJButtoninsertBtn,modifyBtn,deleteBtn; privateJTextAreashow; privateJScrollPaneroll; privateContainercontent; //定義JDBCURL,在客戶端與服務(wù)器之間發(fā)送的所有數(shù)據(jù)使用安全套接字層(SSL)加密,JDBCDriver自動(dòng)信任SQLServerSSL證書 privateStringurl="jdbc:sqlserver://localhost:1433;DatabaseName=performance;encrypt=true;trustServerCertificate=true"; staticConnectionconn; //數(shù)據(jù)庫(kù)連接對(duì)象 staticPreparedStatementpst; //PreparedStatement接口類對(duì)象 staticResultSetrs=null; //結(jié)果集 publicStudentList(){ //構(gòu)造方法 setTitle("編輯成績(jī)表"); //設(shè)置窗口標(biāo)題 setBounds(100,100,370,300); //窗口大小 setResizable(false); //不可改變大小 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //關(guān)閉模式 init(); //調(diào)用成員方法初始化圖形用戶界面 } voidinit(){ content=this.getContentPane(); //獲取容器 content.setLayout(null); //使用絕對(duì)定位進(jìn)行布局 //實(shí)例化三個(gè)按鈕 insertBtn=newJButton("插入記錄"); modifyBtn=newJButton("修改記錄"); deleteBtn=newJButton("刪除記錄"); //設(shè)置按鈕位置和大小 insertBtn.setBounds(5,10,110,30); modifyBtn.setBounds(120,10,110,30); deleteBtn.setBounds(235,10,110,30); //“插入記錄”按鈕注冊(cè)監(jiān)聽器,使用匿名內(nèi)部類處理ActionEvent事件 insertBtn.addActionListener(newActionListener(){ publicvoidactionPerformed(ActionEvente){ Stringsql="insertintoscore(name,Math,Chinese,English)values(?,?,?,?)"; //SQL指令,使用參數(shù)占位符 try{ //連接數(shù)據(jù)庫(kù) conn=DriverManager.getConnection(url,"sa","123456"); pst=conn.prepareStatement(sql); //獲得PreparedStatement對(duì)象 //為各個(gè)占位符賦值 pst.setString(1,"Shally"); pst.setInt(2,96); pst.setInt(3,92); pst.setInt(4,98); pst.executeUpdate(); //執(zhí)行SQL指令 //在文本區(qū)組件中追加操作信息 show.append("插入以下記錄:\n"); show.append("name:Shally\nMath:96\nChinese:92\nEnglish:98\n"); JOptionPane.showMessageDialog(null,"插入成功!");//提示對(duì)話框 //調(diào)用成員方法關(guān)閉結(jié)果集、數(shù)據(jù)連接和PreparedStatement對(duì)象 close(rs,conn,pst); }catch(Exceptione1){ //捕獲異常 e1.printStackTrace(); JOptionPane.showMessageDialog(null,"插入失敗,請(qǐng)確保學(xué)生姓名Shally不存在!"); } } }); content.add(insertBtn); //將按鈕添加到容器中 //“修改記錄”按鈕注冊(cè)監(jiān)聽器,使用匿名內(nèi)部類處理ActionEvent事件 modifyBtn.addActionListener(newActionListener(){ publicvoidactionPerformed(ActionEvente){ Stringsql="updatescoresetMath=92wherename='Alex'"; try{ conn=DriverManager.getConnection(url,"sa","123456"); pst=conn.prepareStatement(sql); pst.executeUpdate(); show.append("Alex的Math成績(jī)修改為92!\n"); JOptionPane.showMessageDialog(null,"修改成功!"); close(rs,conn,pst); }catch(Exceptione2){ e2.printStackTrace(); JOptionPane.showMessageDialog(null,"修改失敗,請(qǐng)確保學(xué)生Alex存在!"); } } }); content.add(modifyBtn); //將按鈕添加到容器中 //“刪除記錄”按鈕注冊(cè)監(jiān)聽器,使用匿名內(nèi)部類處理ActionEvent事件 deleteBtn.addActionListener(newActionListener(){ publicvoidactionPerformed(ActionEvente){ Stringsql="deletefromscorewherename='Susie'"; try{ conn=DriverManager.getConnection(url,"sa","123456"); pst=conn.prepareStatement(sql); pst.executeUpdate(); show.append("刪除學(xué)生Susie的成績(jī)!\n"); JOptionPane.showMessageDialog(null,"刪除成功!"); close(rs,conn,pst); }catch(Exceptione3){ e3.printStackTrace(); JOptionPane.showMessageDialog(null,"刪除失敗,請(qǐng)確保學(xué)生Susie存在!"); } } }); content.add(deleteBtn); //將按鈕添加到容器中 show=newJTextArea(); //實(shí)例化文本區(qū)域 roll=newJScrollPane(show); //為文本區(qū)域添加滾動(dòng)條 roll.setBounds(5,50,340,200); //設(shè)置滾動(dòng)面板的位置和大小 //設(shè)置總是顯示滾動(dòng)條 roll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); content.add(roll); //將滾動(dòng)面板添加到容器中 } //定義成員方法,關(guān)閉所有的資源 privatestaticvoidclose(ResultSetrs,Connectionconn,PreparedStatementpst){ try{ if(rs!=null)rs.close(); if(pst!=null)pst.close(); if(conn!=null)conn.close(); }catch(SQLExceptione){ e.printStackTrace(); } }}(3)在項(xiàng)目中添加一個(gè)名為TestConnection的類,添加main()方法,調(diào)用invokeLater()方法使事件派發(fā)線程上的運(yùn)行對(duì)象排隊(duì)更新窗體,具體代碼如下:importjava.awt.EventQueue;publicclassTestConnection{ publicstaticvoidmain(String[]args){ //使事件派發(fā)線程(按鈕單擊事件)上的運(yùn)行對(duì)象排隊(duì),調(diào)用run()方法更新窗體組件 EventQueue.invokeLater(newRunnable(){ publicvoidrun(){ try{ StudentListframe=newStudentList(); //實(shí)例化窗體 frame.setVisible(true);//設(shè)置窗體可見性 }catch(Exceptione){ e.printStackTrace(); } } }); }}(4)在PackageExplorer窗格中右擊項(xiàng)目名稱,選擇BuildPath→ConfigureBuildPath...命令,將JDBC數(shù)據(jù)庫(kù)驅(qū)動(dòng)包mssql-jdbc-10.2.0.jre17.jar添加到當(dāng)前項(xiàng)目的構(gòu)建路徑中。(5)運(yùn)行程序,打開如圖10-11所示的圖形用戶窗口。單擊“插入記錄”按鈕,彈出一個(gè)提示對(duì)話框,并在文本區(qū)域顯示插入的信息,如圖10-12所示。圖10-11圖形用戶界面圖10-12插入記錄(6)單擊“修改記錄”按鈕,彈出一個(gè)提示對(duì)話框,并在文本區(qū)域顯示修改的記錄信息,如圖10-13所示。(7)單擊“刪除記錄”按鈕,彈出一個(gè)提示對(duì)話框,并在文本區(qū)域顯示刪除的記錄信息,如圖10-14所示。圖10-13修改記錄圖10-14刪除記錄此時(shí)打開MicrosoftSQLServerManagementStudio,可以看到經(jīng)過(guò)以上操作后的score數(shù)據(jù)表如圖10-15所示。圖10-15操作后的數(shù)據(jù)表項(xiàng)目總結(jié)項(xiàng)目實(shí)戰(zhàn)為了便于存儲(chǔ)、管理入庫(kù)和出庫(kù)商品,小白決定使用JDBC+SQLServer改進(jìn)、完善進(jìn)銷存管理系統(tǒng)。(1)啟動(dòng)SQLServerManagementStudio并登錄,新建一個(gè)名為products的數(shù)據(jù)庫(kù),然后在數(shù)據(jù)庫(kù)中添加一個(gè)名為inbound的數(shù)據(jù)表。數(shù)據(jù)表的結(jié)構(gòu)如圖10-16所示。圖10-16設(shè)計(jì)數(shù)據(jù)表inbound(2)在Eclipse中復(fù)制并粘貼項(xiàng)目“進(jìn)銷存管理系統(tǒng)V9.0”,在CopyProject對(duì)話框中修改項(xiàng)目名稱為“進(jìn)銷存管理系統(tǒng)V10.0”,然后單擊Copy按鈕關(guān)閉對(duì)話框。(3)在項(xiàng)目中添加與JRE匹配的JDBCJAR包文件(與JRE17匹配的包文件為mssql-jdbc-10.2.0.jre17.jar)。(4)在項(xiàng)目中添加一個(gè)名為data的包,然后在該包中添加一個(gè)名為DBConnect.java的類,用于管理數(shù)據(jù)庫(kù)連接。在該類中定義方法連接數(shù)據(jù)庫(kù)和關(guān)閉數(shù)據(jù)庫(kù)連接,關(guān)鍵代碼如下:……publicclassDBConnect{ //連接數(shù)據(jù)庫(kù)的URL參數(shù) staticfinalStringurl="jdbc:sqlserver://localhost:1433;" +"DatabaseName=products;encrypt=true;" +"trustServerCertificate=true"; staticfinalStringuser="sa"; //用戶名 staticfinalStringpassword="123456"; //密碼 //獲取數(shù)據(jù)庫(kù)連接對(duì)象 publicstaticConnectiongetConnection(){ try{//連接指定的數(shù)據(jù)庫(kù)并返回連接對(duì)象 returnDriverManager.getConnection(url,user,password); }catch(SQLExceptione){ e.printStackTrace(); returnnull; } } //關(guān)閉打開的數(shù)據(jù)庫(kù)連接、結(jié)果集和SQL語(yǔ)句對(duì)象 publicstaticvoidcloseConnection(ResultSetrs,Statementst,Connectionconn){ try{ if(rs!=null) rs.close(); if(st!=null) st.close(); if(conn!=null) conn.close(); }catch(SQLExceptione){ e.printStackTrace(); } } //如果結(jié)果集為空,關(guān)閉數(shù)據(jù)庫(kù)連接和SQL語(yǔ)句 publicstaticvoidcloseConnection(Statementst,Connectionconn){ closeConnection(null,st,conn); }}(5)修改ServerControllers.java,通過(guò)操作數(shù)據(jù)庫(kù)處理商品入庫(kù)、出庫(kù)和查詢的操作。關(guān)鍵代碼如下:……publicclassServerControllers{ //處理商品入庫(kù)請(qǐng)求 publicResultsaddGoods(Goodsgoods){ Resultsresult=newResults(); try{ Connectionconn=DBConnect.getConnection();//獲取連接 Statementst=conn.createStatement(); //創(chuàng)建SQL語(yǔ)句對(duì)象 Stringsql="insertintoinbound(name,num,price)values('"+goods.getName()+"',"+goods.getNum()+","+goods.getPrice()+")"; st.execute(sql); //執(zhí)行SQL語(yǔ)句 DBConnect.closeConnection(st,conn); //關(guān)閉連接 result.setSuccess(true); //返回操作結(jié)果 returnresult; }catch(SQLExceptione){ e.printStackTrace(); result.setSuccess(false); returnresult; } } //處理商品出庫(kù)請(qǐng)求 publicResultsoutGoods(Goodsgoods){ Connectionconn=DBConnect.getConnection(); //獲取連接 Resultsresult=newResults(); //定義結(jié)果集 try{ //創(chuàng)建SQL語(yǔ)句對(duì)象 Statementst=conn.createStatement(); Stringsql="selectname,numfrominboundwherename='"+goods.getName()+"'"; //執(zhí)行語(yǔ)句并返回結(jié)果集 ResultSet

溫馨提示

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

評(píng)論

0/150

提交評(píng)論