![Java開發(fā)綜合實(shí)戰(zhàn) 教案 項(xiàng)目十 訪問數(shù)據(jù)庫_第1頁](http://file4.renrendoc.com/view10/M01/39/31/wKhkGWWuVh2AIGQnAAD48aoumxs540.jpg)
![Java開發(fā)綜合實(shí)戰(zhàn) 教案 項(xiàng)目十 訪問數(shù)據(jù)庫_第2頁](http://file4.renrendoc.com/view10/M01/39/31/wKhkGWWuVh2AIGQnAAD48aoumxs5402.jpg)
![Java開發(fā)綜合實(shí)戰(zhàn) 教案 項(xiàng)目十 訪問數(shù)據(jù)庫_第3頁](http://file4.renrendoc.com/view10/M01/39/31/wKhkGWWuVh2AIGQnAAD48aoumxs5403.jpg)
![Java開發(fā)綜合實(shí)戰(zhàn) 教案 項(xiàng)目十 訪問數(shù)據(jù)庫_第4頁](http://file4.renrendoc.com/view10/M01/39/31/wKhkGWWuVh2AIGQnAAD48aoumxs5404.jpg)
![Java開發(fā)綜合實(shí)戰(zhàn) 教案 項(xiàng)目十 訪問數(shù)據(jù)庫_第5頁](http://file4.renrendoc.com/view10/M01/39/31/wKhkGWWuVh2AIGQnAAD48aoumxs5405.jpg)
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
STYLEREFbt1a項(xiàng)目十STYLEREFbt1b訪問數(shù)據(jù)庫項(xiàng)目十訪問數(shù)據(jù)庫思政目標(biāo)找對學(xué)習(xí)方法,注重前后知識的遷移,能舉一反三。鼓勵(lì)應(yīng)用創(chuàng)新,引導(dǎo)學(xué)生融會(huì)貫通,增強(qiáng)實(shí)踐能力。技能目標(biāo)能夠利用常用的SQL語句查詢、更新、添加和刪除記錄。能夠使用JDBC操作數(shù)據(jù)庫中的數(shù)據(jù)。項(xiàng)目導(dǎo)讀在開發(fā)應(yīng)用程序的過程中,數(shù)據(jù)庫扮演著十分重要的角色,絕大多數(shù)的應(yīng)用都需要使用數(shù)據(jù)庫來存儲(chǔ)和管理數(shù)據(jù)。JAVA提供了專門用于操作數(shù)據(jù)庫的API,即JDBC(JavaDatabaseConnectivity,Java數(shù)據(jù)庫連接),可以很容易地訪問不同的數(shù)據(jù)庫,對數(shù)據(jù)庫中的記錄實(shí)現(xiàn)查詢、修改、刪除和添加等操作。Java開發(fā)綜合實(shí)戰(zhàn)任務(wù)1SQL語法基礎(chǔ)任務(wù)引入小白創(chuàng)建的進(jìn)銷存管理系統(tǒng)使用數(shù)組存儲(chǔ)商品信息,為便于后期的數(shù)據(jù)擴(kuò)容和管理,他決定利用數(shù)據(jù)庫存儲(chǔ)、管理商品數(shù)據(jù)。為熟悉數(shù)據(jù)查詢操作,他使用SQLServer創(chuàng)建了一個(gè)存儲(chǔ)學(xué)生成績的數(shù)據(jù)庫performance,并創(chuàng)建了一個(gè)成績表score、錄入了數(shù)據(jù)。如果他要查詢、更新、添加或刪除數(shù)據(jù)庫中的數(shù)據(jù),可以使用什么語句呢?知識準(zhǔn)備訪問數(shù)據(jù)庫要使用SQL語句。SQL(StructuredQueryLanguage,結(jié)構(gòu)查詢語言)是一個(gè)用于與數(shù)據(jù)庫通信的數(shù)據(jù)庫語言,是關(guān)系數(shù)據(jù)庫管理系統(tǒng)的標(biāo)準(zhǔn)語言。SQL語句主要有以下3大類,每一類語言包含或多或少的語句,使用在不同的應(yīng)用程序中。數(shù)據(jù)定義語言(DDL):用于定義數(shù)據(jù)的結(jié)構(gòu),例如創(chuàng)建、修改或刪除數(shù)據(jù)庫或數(shù)據(jù)庫中的對象(如表、視圖、存儲(chǔ)過程、觸發(fā)器等)。數(shù)據(jù)操縱語言(DML):用于操作數(shù)據(jù)表中的數(shù)據(jù),主要包括數(shù)據(jù)的插入、刪除、更新、查找、過濾和排序等,是最常用的核心SQL語言。數(shù)據(jù)控制語言(DCL):用于分配數(shù)據(jù)庫用戶的權(quán)限。在一般的應(yīng)用程序中使用較多的是數(shù)據(jù)操縱語言,可以使用CRUD概括地表示對數(shù)據(jù)庫的常見操作,即表的創(chuàng)建(Create)、數(shù)據(jù)檢索(Retrieve)、數(shù)據(jù)更新(Update)和刪除(Delete)操作。SQL語言很復(fù)雜也很龐大,因篇幅所限,本節(jié)僅簡要介紹常用的幾個(gè)數(shù)據(jù)操縱語句,更多的SQL語句讀者可以查閱相關(guān)資料。一、select語句該語句用于在數(shù)據(jù)表中檢索符合查詢條件的數(shù)據(jù)行,僅包含指定的字段。其語法格式如下:SELECT所選字段列表FROM數(shù)據(jù)表名[WHERE查詢條件表達(dá)式][ORDERBY字段名[ASC|DESC]如果要檢索數(shù)據(jù)表中的所有列,可以使用通配符(*)替代字段列表。ORDER子句用于將查詢結(jié)果集按照某個(gè)字段值進(jìn)行排序,關(guān)鍵字ASC表示升序,DESC表示降序。案例——查詢成績表SQLServer數(shù)據(jù)庫performance中的score表由一群學(xué)生的成績數(shù)據(jù)組成,每一行包含四個(gè)字段,即學(xué)生姓名、數(shù)學(xué)成績、語文成績和外語成績,如圖10-1所示。圖10-1score表如果要查詢該表中數(shù)學(xué)成績在90及以上的學(xué)生名單及對應(yīng)的數(shù)學(xué)成績,并將結(jié)果按降序排列,可以利用如下SQL語句:SELECTname,MathFROMscoreWHERE(Math>=90)ORDERBYMathDESC查詢的結(jié)果如圖10-2所示。圖10-2select命令查詢結(jié)果二、insert語句INSERT語句用于在一個(gè)表中插入單行或多行數(shù)據(jù),同時(shí)賦給每個(gè)列相應(yīng)的值,如果這個(gè)值支持它們定義的物理順序中的所有的值,則不需要字段名。其語法格式如下:INSERT[INTO]表名或視圖名[(字段列表)]VALUES(字段值列表)例如,下面的語句在表score中插入了學(xué)生Alex的成績記錄:INSERTINTOscore(name,Math,Chinese,English)VALUES('Alex',87,93,92)其中,字段列表可以省略。執(zhí)行上面的語句后,表score如圖10-3示。圖10-3插入記錄后的score表三、update語句UPDATE語句用于根據(jù)查詢條件更新數(shù)據(jù)表中的某些字段值。其語法格式如下:UPDATE數(shù)據(jù)表名SET字段名1=字段值1,字段名2=字段值2……WHERE條件表達(dá)式例如,使用以下語句,可以在表score中修改olivia的數(shù)學(xué)和英語成績:UPDATEscoreSETMath=89,English=92WHERE(name='Olivia')注意:SQL語句中的字符串應(yīng)包含在單引號中。該語句執(zhí)行之后,表score如圖10-4所示。圖10-4更新記錄后的score表四、delete語句該語句用于在數(shù)據(jù)庫中刪除符合指定條件的數(shù)據(jù)行,其語法格式如下:DELETEFROM數(shù)據(jù)表名[WHERE條件表達(dá)式]如果有查詢條件,則刪除與查詢條件相符的數(shù)據(jù)行;如果沒有查詢條件,將刪除所有的記錄。例如,下面的語句刪除表score中語文成績小于90分的成績記錄:DELETEFROMscoreWHERE(Chinese<90)執(zhí)行上面的語句后,score表如圖10-5所示。圖10-5刪除記錄后的score表任務(wù)2使用JDBC訪問數(shù)據(jù)庫任務(wù)引入小白掌握了常用的查詢語句后,想利用圖形用戶界面修改數(shù)據(jù)庫中的數(shù)據(jù),但是怎樣將數(shù)據(jù)庫與Java應(yīng)用程序關(guān)聯(lián)起來呢?他查看相關(guān)資料得知,JDBC為連接數(shù)據(jù)庫提供了統(tǒng)一的規(guī)范,決定采用JDBC訪問數(shù)據(jù)庫。接下來該如何在系統(tǒng)中部署JDBC,連接數(shù)據(jù)庫呢?查詢數(shù)據(jù)后怎樣輸出滿足條件的數(shù)據(jù)記錄呢?知識準(zhǔn)備一、JDBC概述JDBC是一套用于執(zhí)行SQL語句的JavaAPI,提供了一套數(shù)據(jù)庫操作標(biāo)準(zhǔn),可以采用相同的API實(shí)現(xiàn)對多種關(guān)系型數(shù)據(jù)庫的統(tǒng)一操作,從而提高Java程序多數(shù)據(jù)庫的可移植性。簡單來說,JDBC能完成下列三種功能:與一個(gè)數(shù)據(jù)庫建立連接向數(shù)據(jù)庫發(fā)送SQL語句處理數(shù)據(jù)庫返回的結(jié)果JDBC由兩層構(gòu)成:上層是JDBCAPI,負(fù)責(zé)在Java應(yīng)用程序和JDBC驅(qū)動(dòng)程序管理器之間進(jìn)行通信,發(fā)送程序中的SQL語;下層是JDBC驅(qū)動(dòng)程序API,負(fù)責(zé)JDBC驅(qū)動(dòng)程序管理器與實(shí)際連接的數(shù)據(jù)庫的廠商驅(qū)動(dòng)程序和第三方驅(qū)動(dòng)程序之間進(jìn)行通信,返回查詢信息或者執(zhí)行規(guī)定的操作。如果要使用JDBC訪問某種數(shù)據(jù)庫中的數(shù)據(jù),計(jì)算機(jī)上必須安裝有JDBC驅(qū)動(dòng)程序。二、部署JDBC驅(qū)動(dòng)程序JDBC針對每一個(gè)數(shù)據(jù)庫廠商都提供了一個(gè)JDBC驅(qū)動(dòng)程序。在連接到數(shù)據(jù)庫之前,必須首先在本地計(jì)算機(jī)上安裝數(shù)據(jù)庫和JDBC驅(qū)動(dòng)程序。不同版本的JDBC驅(qū)動(dòng)程序?qū)RE的要求也不相同,因此部署JDBC驅(qū)動(dòng)程序之前,要先選擇正確的JAR類庫文件。例如MicrosoftJDBCDriver10.2安裝包中包含三個(gè)JAR類庫: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)要求可參見對應(yīng)數(shù)據(jù)庫的官網(wǎng)說明。由于JDBC類庫文件不是JavaSDK的一部分,因此,在下載合適的類庫文件后,應(yīng)將jar類庫文件包含在用戶應(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)行訪問數(shù)據(jù)庫的Java項(xiàng)目,需要將JDBC數(shù)據(jù)庫驅(qū)動(dòng)包添加到當(dāng)前項(xiàng)目的構(gòu)建路徑中,步驟如下。(1)在Eclipse中右擊項(xiàng)目名,從彈出的快捷菜單中選擇BuildPath→ConfigureBuildPath...命令。(2)在打開的對話框左側(cè)窗格中選中“JavaBuildPath”節(jié)點(diǎn),然后在Libraries選項(xiàng)卡中選中Classpath,單擊AddLibrary...按鈕,如圖10-7所示。(3)在打開的AddLibrary對話框的庫列表框中選擇“UserLibrary”,然后單擊Next按鈕,在彈出的對話框中,依次單擊UserLibraries按鈕,New按鈕,新建一個(gè)用戶庫的名稱。(4)依次單擊OK按鈕和ApplyandClose按鈕關(guān)閉對話框。然后單擊AddExternalJARs按鈕,在打開的對話框中選擇與JRE匹配的JDBCJAR包文件(比如與JRE17匹配的mssql-jdbc-10.2.0.jre17.jar)。單擊“打開”按鈕關(guān)閉對話框,此時(shí)可以看到新建的用戶庫如圖10-8所示。圖10-7項(xiàng)目屬性對話框圖10-8創(chuàng)建的用戶庫(5)依次單擊ApplyandClose按鈕和Finish按鈕關(guān)閉對話框。此時(shí)在項(xiàng)目的屬性對話框中可以看到添加的類庫路徑,如圖10-9所示。圖10-9添加的類庫路徑(6)添加完成后,單擊ApplyandClose按鈕關(guān)閉對話框。三、連接數(shù)據(jù)庫使用JDBC數(shù)據(jù)庫驅(qū)動(dòng)方式和數(shù)據(jù)庫建立連接需要經(jīng)過兩個(gè)步驟:(1)注冊JDBC驅(qū)動(dòng)程序;(2)與指定數(shù)據(jù)庫建立連接。這些操作使用JDBC中的Driver接口、DriverManager類和Connection接口實(shí)現(xiàn)。1.注冊驅(qū)動(dòng)程序注冊驅(qū)動(dòng)程序就是將特定數(shù)據(jù)庫的驅(qū)動(dòng)程序類裝載到JVM。每種數(shù)據(jù)庫的驅(qū)動(dòng)程序都提供一個(gè)實(shí)現(xiàn)Driver接口的類,簡稱Driver類,是應(yīng)用程序必須首先加載的類,用于向驅(qū)動(dòng)程序管理器(java.sql.DriverManager類)注冊該類的實(shí)例,以便驅(qū)動(dòng)程序管理器管理數(shù)據(jù)庫驅(qū)動(dòng)程序。在JDBCAPI4.0之前,通常使用java.lang.Class類的靜態(tài)方法forName(className)加載要連接的數(shù)據(jù)庫驅(qū)動(dòng)程序類,并將加載的類自動(dòng)向DriverManager類注冊,參數(shù)為要加載的數(shù)據(jù)庫驅(qū)動(dòng)程序的完整類名。如果加載失敗,則拋出ClassNotFoundException異常。例如,下面的程序段可用于檢測SQLServer數(shù)據(jù)庫驅(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ù)庫驅(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庫時(shí),應(yīng)用程序無需調(diào)用Class.forName方法注冊驅(qū)動(dòng)程序。當(dāng)前通過使用Class.forName方法加載驅(qū)動(dòng)程序的現(xiàn)有應(yīng)用程序仍可繼續(xù)工作,無需進(jìn)行修改。2.建立連接注冊數(shù)據(jù)庫驅(qū)動(dòng)程序后,JVM和數(shù)據(jù)庫之間還沒有直接聯(lián)系,需要調(diào)用DriverManager類的靜態(tài)方法getConnection()方法獲得一個(gè)數(shù)據(jù)庫連接對象,建立Java應(yīng)用程序與指定數(shù)據(jù)庫之間的聯(lián)系。建立數(shù)據(jù)庫連接對象的過程涉及兩個(gè)主要API:java.sql.DriverManager類和java.sql.Connection接口。DriverManager是JDBC用于管理驅(qū)動(dòng)程序的類,主要用于管理用戶程序與特定數(shù)據(jù)庫的連接。Connection接口類對象是應(yīng)用程序連接數(shù)據(jù)庫的連接對象,主要作用是調(diào)用createStatement()方法創(chuàng)建語句對象。DriverManager類有如下兩個(gè)用于建立連接的靜態(tài)方法:Connectionconn=DriverManager.getConnection(URL,user,password);Connectionconn=DriverManager.getConnection(URL);URL參數(shù)是每個(gè)JDBC驅(qū)動(dòng)程序?qū)S玫腏DBCURL,語法格式如下:jdbc:子協(xié)議:數(shù)據(jù)庫定位器子協(xié)議與JDBC驅(qū)動(dòng)程序有關(guān),根據(jù)實(shí)際的JDBC驅(qū)動(dòng)程序廠商而不同。提示:不同版本的SQLServer數(shù)據(jù)庫的子協(xié)議有所不同。SQLServer2005之前的版本為microsoft:sqlserver;而SQLServer2005及之后的版本子協(xié)議為sqlserver。數(shù)據(jù)庫定位器用于指定要與應(yīng)用程序進(jìn)行交互的數(shù)據(jù)庫,根據(jù)驅(qū)動(dòng)程序的類型,可能包括主機(jī)名、端口和數(shù)據(jù)庫系統(tǒng)名。例如:連接SQLServer數(shù)據(jù)庫sample的URL為"jdbc:sqlserver://localhost:1433;DatabaseName=sample"。localhost(或127.0.0.1)表示本機(jī)地址,1433是SQLServer的默認(rèn)端口號,sample是數(shù)據(jù)庫名稱。很多驅(qū)動(dòng)程序還接受在URL末尾附加參數(shù),如數(shù)據(jù)庫賬號的用戶名和密碼,此時(shí)采用getConnection()方法的第二種格式。例如:以下語句連接MySQL數(shù)據(jù)庫sample:Stringurl="jdbc:mysql://localhost:3306/sample?user=root&password=123";Connectionconn=DriverManager.getConnection(url);參數(shù)user和password分別為用戶登錄數(shù)據(jù)庫管理系統(tǒng)的用戶名及密碼。如果沒有設(shè)置用戶名和密碼,參數(shù)設(shè)置為空即可。由于getConnection()方法可能拋出SQLException異常,因此在程序中應(yīng)捕獲異常。例如,與SQLServer數(shù)據(jù)源student建立連接的語句如下:try{Stringurl="jdbc:sqlserver://localhost:1433;DatabaseName=student";Connectioncon=DriverManager.getConnection(url,"sa","123456");}catch(SQLExceptione){ //處理異常}注意:如果數(shù)據(jù)庫表的記錄包含漢字,在建立連接時(shí)應(yīng)在URL參數(shù)中附加一個(gè)characterEncoding參數(shù),值為utf-8或gb2312。四、操作數(shù)據(jù)庫與數(shù)據(jù)庫建立連接后,就可以使用JDBC提供的API與數(shù)據(jù)庫進(jìn)行交互。交互的主要方式是使用SQL語句,JDBC將標(biāo)準(zhǔn)的SQL語句發(fā)送給數(shù)據(jù)庫,數(shù)據(jù)庫執(zhí)行指令并處理查詢結(jié)果,返回結(jié)果集。1.發(fā)送、執(zhí)行SQL指令向數(shù)據(jù)庫發(fā)送SQL指令需要使用Statement接口類對象聲明一個(gè)SQL語句,然后通過創(chuàng)建的數(shù)據(jù)庫連接對象調(diào)用方法createStatement()創(chuàng)建這個(gè)SQL語句對象,語法格式如下:try{ Statementsql=con.createStatement();}catch(SQLExceptione){//處理異常}Statement接口定義了執(zhí)行語句和獲取結(jié)果的基本方法,用于將不帶參數(shù)的簡單SQL語句發(fā)送到數(shù)據(jù)庫,并獲取指定SQL語句的執(zhí)行結(jié)果。Statement接口包含以下3種執(zhí)行SQL語句的方法。execute(Stringsql):可執(zhí)行任何SQL語句,返回結(jié)果為布爾值。如果值為true,表明有結(jié)果集,通常是執(zhí)行了select查詢語句;如果值為false,表明沒有結(jié)果集,通常是執(zhí)行了insert、delete、update等增刪改語句。executeQuery(Stringsql):通常執(zhí)行select查詢語句,返回單個(gè)ResultSet結(jié)果集。executeUpdate(Stringsql):常用于執(zhí)行DML和DDL語句,返回值為int型。執(zhí)行DML語句時(shí)返回受SQL語句影響的數(shù)據(jù)行數(shù);執(zhí)行DDL語句返回0。當(dāng)Connection對象處于默認(rèn)狀態(tài)時(shí),所有Statement對象都是自動(dòng)執(zhí)行的,也就是說,當(dāng)Statement語句對象執(zhí)行SQL語句時(shí),該SQL語句馬上提交數(shù)據(jù)庫并返回結(jié)果。如果將連接修改為手動(dòng)提交的事務(wù)模式,則只有執(zhí)行commit()方法時(shí),才會(huì)提交相應(yīng)的數(shù)據(jù)庫操作。Statement對象使用完畢后,最好使用close()方法將其關(guān)閉。如果要執(zhí)行動(dòng)態(tài)SQL語句,可使用PreparedStatement接口類對象,該接口繼承自Statement接口,具有Statement接口的所有方法。由于PreparedStatement實(shí)例對象保存有已被預(yù)編譯的SQL語句,因此執(zhí)行速度比Statement對象快。通過調(diào)用Connection接口對象的preparedStatement()方法可獲得PreparedStatement對象,語法格式如下:Connectionconn=DriverManager.getConnection(url,"user","password");PreparedStatementpstmt=conn.preparedStatement(Stringsql);從上面的語法格式可以看到,使用preparedStatement()方法創(chuàng)建PreparedStatement對象時(shí),需要SQL命令字符串作為參數(shù),以實(shí)現(xiàn)SQL命令預(yù)編譯。在SQL命令中可以包含一個(gè)或多個(gè)IN參數(shù),也可以使用“?”作為占位符。在調(diào)用executeQuery()或executeUpdate()方法之前,使用如表10-1所示的setXxx()方法為占位符賦值。表10-1PreparedStatement接口常用的方法方法說明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ù)表方法說明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對象在score表中插入一條記錄:try{//包含4個(gè)占位符的SQL命令Stringsql="insertintoscore(name,Math,Chinese,English)values(?,?,?,?)";//創(chuàng)建PreparedStatement對象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語句是查詢語句,將返回一個(gè)ResultSet對象存放查詢結(jié)果。ResultSet對象由按字段組織的數(shù)據(jù)行構(gòu)成,并具有指向當(dāng)前數(shù)據(jù)行的游標(biāo)。當(dāng)獲得一個(gè)ResultSet時(shí),游標(biāo)指向第一行記錄之前的位置,一次只能看到一個(gè)數(shù)據(jù)行。通過next()方法可移動(dòng)到下一個(gè)數(shù)據(jù)行,沒有下一行時(shí)返回false。獲得一行數(shù)據(jù)后,ResultSet對象可以使用如表10-2所示的getXxx()方法獲得字段值,方法的參數(shù)可以是字段的位置索引或者是字段的名稱。表10-2獲取結(jié)果集字段值的常用方法方法說明getInt(intcolumnIndex)或getInt(StringcolumnLabel)以int形式返回ResultSet對象當(dāng)前數(shù)據(jù)行指定列的值。如果列值為NULL,返回0getFloat(intcolumnIndex)或getFloat(StringcolumnLabel)以float形式返回ResultSet對象當(dāng)前數(shù)據(jù)行指定列的值。如果列值為NULL,返回0getDate(intcolumnIndex)或getDate(StringcolumnLabel)以date形式返回ResultSet對象當(dāng)前數(shù)據(jù)行指定列的值。如果列值為NULL,返回null
續(xù)表方法說明getBoolean(intcolumnIndex)或getBoolean(StringcolumnLabel)以Boolean形式返回ResultSet對象當(dāng)前數(shù)據(jù)行指定列的值。如果列值為NULL,返回nullgetString(intcolumnIndex)或getString(StringcolumnLabel)以String形式返回ResultSet對象當(dāng)前數(shù)據(jù)行指定列的值。如果列值為NULL,返回null默認(rèn)情況下,ResultSet的游標(biāo)只能向下一行單向移動(dòng),如果要在結(jié)果集中向前移動(dòng)、或顯示結(jié)果集指定的某條記錄,則需要調(diào)用數(shù)據(jù)庫連接對象的createStatement(inttype,intconcurrency)方法創(chuàng)建一個(gè)Statement對象,然后執(zhí)行SQL語句返回一個(gè)可以滾動(dòng)的結(jié)果集。語法格式如下:Statementst=conn.createStatement(inttype,intconcurrency);ResultSetrs=st.executeQuery(Stringsql);其中,type的取值(如表10-3所示)決定滾動(dòng)方式;concurrency取值(如表10-4所示)決定是否可以用結(jié)果集更新數(shù)據(jù)庫。表10-3參數(shù)type的取值值含義ResultSet.TYPE_FORWORD_ONLY游標(biāo)只能向下移動(dòng)ResultSet.TYPE_SCROLL_INSENSITIVE游標(biāo)可以上下移動(dòng),數(shù)據(jù)庫變化時(shí),當(dāng)前結(jié)果集不變ResultSet.TYPE_SCROLL_SENSITIVE游標(biāo)可以上下移動(dòng),數(shù)據(jù)庫變化時(shí),當(dāng)前結(jié)果集同步改變表10-4參數(shù)concurrency的取值值含義ResultSet.CONCUR_READ_ONLY不能用結(jié)果集更新數(shù)據(jù)庫中的表ResultSet.CONCUR_UPDATETABLE能用結(jié)果集更新數(shù)據(jù)庫中的表創(chuàng)建可滾動(dòng)的結(jié)果集后,利用ResultSet接口提供的一些方法可以很方便地在結(jié)果集中移動(dòng)游標(biāo),如表10-5所示。表10-5移動(dòng)游標(biāo)的常用方法方法說明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指定的行號。需要注意的是,如果row為負(fù)值,表示倒數(shù)的行數(shù),即absolute(-1)表示移動(dòng)到最后一行在結(jié)果集中移動(dòng)游標(biāo)后,使用getRow()方法可以獲取游標(biāo)所指行的行號,如果結(jié)果集沒有行,則返回0。使用isFirst()和isLast()方法可以分別判斷游標(biāo)是否指向結(jié)果集的第一行和最后一行。注意:對數(shù)據(jù)庫進(jìn)行操作時(shí),返回的ResultSet對象與Connection對象是有緊密聯(lián)系的,如果使用close()方法關(guān)閉連接對象,ResultSet對象中的數(shù)據(jù)會(huì)即刻消失。因此,應(yīng)在數(shù)據(jù)庫操作結(jié)束后關(guān)閉數(shù)據(jù)庫連接,釋放資源,包括關(guān)閉ResultSet和Statement等資源。案例——修改學(xué)生成績表本案例利用圖形用戶界面修改SQLServer數(shù)據(jù)庫performance中的學(xué)生成績表score。成績表score的初始數(shù)據(jù)行如圖10-10所示。圖10-10初始數(shù)據(jù)表(1)在Eclipse中新建一個(gè)名為StudentQuery的Java項(xiàng)目。然后在項(xiàng)目中添加一個(gè)名為StudentList的類,創(chuàng)建用戶界面,為按鈕注冊監(jiān)聽器,監(jiān)聽ActiveEvent事件,并使用匿名內(nèi)部類訪問數(shù)據(jù)庫,處理按鈕的動(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ù)庫連接對象 staticPreparedStatementpst; //PreparedStatement接口類對象 staticResultSetrs=null; //結(jié)果集 publicStudentList(){ //構(gòu)造方法 setTitle("編輯成績表"); //設(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); //使用絕對定位進(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); //“插入記錄”按鈕注冊監(jiān)聽器,使用匿名內(nèi)部類處理ActionEvent事件 insertBtn.addActionListener(newActionListener(){ publicvoidactionPerformed(ActionEvente){ Stringsql="insertintoscore(name,Math,Chinese,English)values(?,?,?,?)"; //SQL指令,使用參數(shù)占位符 try{ //連接數(shù)據(jù)庫 conn=DriverManager.getConnection(url,"sa","123456"); pst=conn.prepareStatement(sql); //獲得PreparedStatement對象 //為各個(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,"插入成功!");//提示對話框 //調(diào)用成員方法關(guān)閉結(jié)果集、數(shù)據(jù)連接和PreparedStatement對象 close(rs,conn,pst); }catch(Exceptione1){ //捕獲異常 e1.printStackTrace(); JOptionPane.showMessageDialog(null,"插入失敗,請確保學(xué)生姓名Shally不存在!"); } } }); content.add(insertBtn); //將按鈕添加到容器中 //“修改記錄”按鈕注冊監(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成績修改為92!\n"); JOptionPane.showMessageDialog(null,"修改成功!"); close(rs,conn,pst); }catch(Exceptione2){ e2.printStackTrace(); JOptionPane.showMessageDialog(null,"修改失敗,請確保學(xué)生Alex存在!"); } } }); content.add(modifyBtn); //將按鈕添加到容器中 //“刪除記錄”按鈕注冊監(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的成績!\n"); JOptionPane.showMessageDialog(null,"刪除成功!"); close(rs,conn,pst); }catch(Exceptione3){ e3.printStackTrace(); JOptionPane.showMessageDialog(null,"刪除失敗,請確保學(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ì)更新窗體,具體代碼如下:importjava.awt.EventQueue;publicclassTestConnection{ publicstaticvoidmain(String[]args){ //使事件派發(fā)線程(按鈕單擊事件)上的運(yùn)行對象排隊(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ù)庫驅(qū)動(dòng)包mssql-jdbc-10.2.0.jre17.jar添加到當(dāng)前項(xiàng)目的構(gòu)建路徑中。(5)運(yùn)行程序,打開如圖10-11所示的圖形用戶窗口。單擊“插入記錄”按鈕,彈出一個(gè)提示對話框,并在文本區(qū)域顯示插入的信息,如圖10-12所示。圖10-11圖形用戶界面圖10-12插入記錄(6)單擊“修改記錄”按鈕,彈出一個(gè)提示對話框,并在文本區(qū)域顯示修改的記錄信息,如圖10-13所示。(7)單擊“刪除記錄”按鈕,彈出一個(gè)提示對話框,并在文本區(qū)域顯示刪除的記錄信息,如圖10-14所示。圖10-13修改記錄圖10-14刪除記錄此時(shí)打開MicrosoftSQLServerManagementStudio,可以看到經(jīng)過以上操作后的score數(shù)據(jù)表如圖10-15所示。圖10-15操作后的數(shù)據(jù)表項(xiàng)目總結(jié)項(xiàng)目實(shí)戰(zhàn)為了便于存儲(chǔ)、管理入庫和出庫商品,小白決定使用JDBC+SQLServer改進(jìn)、完善進(jìn)銷存管理系統(tǒng)。(1)啟動(dòng)SQLServerManagementStudio并登錄,新建一個(gè)名為products的數(shù)據(jù)庫,然后在數(shù)據(jù)庫中添加一個(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對話框中修改項(xiàng)目名稱為“進(jìn)銷存管理系統(tǒng)V10.0”,然后單擊Copy按鈕關(guān)閉對話框。(3)在項(xiàng)目中添加與JRE匹配的JDBCJAR包文件(與JRE17匹配的包文件為mssql-jdbc-10.2.0.jre17.jar)。(4)在項(xiàng)目中添加一個(gè)名為data的包,然后在該包中添加一個(gè)名為DBConnect.java的類,用于管理數(shù)據(jù)庫連接。在該類中定義方法連接數(shù)據(jù)庫和關(guān)閉數(shù)據(jù)庫連接,關(guān)鍵代碼如下:……publicclassDBConnect{ //連接數(shù)據(jù)庫的URL參數(shù) staticfinalStringurl="jdbc:sqlserver://localhost:1433;" +"DatabaseName=products;encrypt=true;" +"trustServerCertificate=true"; staticfinalStringuser="sa"; //用戶名 staticfinalStringpassword="123456"; //密碼 //獲取數(shù)據(jù)庫連接對象 publicstaticConnectiongetConnection(){ try{//連接指定的數(shù)據(jù)庫并返回連接對象 returnDriverManager.getConnection(url,user,password); }catch(SQLExceptione){ e.printStackTrace(); returnnull; } } //關(guān)閉打開的數(shù)據(jù)庫連接、結(jié)果集和SQL語句對象 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ù)庫連接和SQL語句 publicstaticvoidcloseConnection(Statementst,Connectionconn){ closeConnection(null,st,conn); }}(5)修改ServerControllers.java,通過操作數(shù)據(jù)庫處理商品入庫、出庫和查詢的操作。關(guān)鍵代碼如下:……publicclassServerControllers{ //處理商品入庫請求 publicResultsaddGoods(Goodsgoods){ Resultsresult=newResults(); try{ Connectionconn=DBConnect.getConnection();//獲取連接 Statementst=conn.createStatement(); //創(chuàng)建SQL語句對象 Stringsql="insertintoinbound(name,num,price)values('"+goods.getName()+"',"+goods.getNum()+","+goods.getPrice()+")"; st.execute(sql); //執(zhí)行SQL語句 DBConnect.closeConnection(st,conn); //關(guān)閉連接 result.setSuccess(true); //返回操作結(jié)果 returnresult; }catch(SQLExceptione){ e.printStackTrace(); result.setSuccess(false); returnresult; } } //處理商品出庫請求 publicResultsoutGoods(Goodsgoods){ Connectionconn=DBConnect.getConnection(); //獲取連接 Resultsresult=newResults(); //定義結(jié)果集 try{ //創(chuàng)建SQL語句對象 Statementst=conn.createStatement(); Stringsql="selectname,numfrominboundwherename='"+goods.getName()+"'"; //執(zhí)行語句并返回結(jié)果集 ResultSet
溫馨提示
- 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025-2030全球風(fēng)電用工業(yè)碳刷行業(yè)調(diào)研及趨勢分析報(bào)告
- 2025-2030全球服裝金屬探測器行業(yè)調(diào)研及趨勢分析報(bào)告
- 2025年全球及中國高性能航空涂料行業(yè)頭部企業(yè)市場占有率及排名調(diào)研報(bào)告
- 2025年全球及中國眼科手術(shù)剪行業(yè)頭部企業(yè)市場占有率及排名調(diào)研報(bào)告
- 2025公路工程進(jìn)度、計(jì)量、合同管理監(jiān)理內(nèi)容
- 餐桌茶幾家具買賣合同
- 年貨物運(yùn)輸合同范本
- 2025合同模板合伙協(xié)議范本
- 大米購銷的合同
- 物聯(lián)網(wǎng)系統(tǒng)定制與開發(fā)合同
- 渠道管理就這樣做
- 大客戶銷售這樣說這樣做
- 精裝修樣板房房屋使用說明
- 喬遷新居結(jié)婚典禮主持詞
- 小學(xué)四年級數(shù)學(xué)競賽試題(附答案)
- 魯科版高中化學(xué)必修2全冊教案
- 《病理學(xué)基礎(chǔ)》知識考核試題題庫與答案
- 人口分布 高一地理下學(xué)期人教版 必修第二冊
- 四年級上冊英語試題-Module 9 Unit 1 What happened to your head--外研社(一起)(含答案)
- 子宮內(nèi)膜異位癥診療指南
- 《高級計(jì)量經(jīng)濟(jì)學(xué)》-上課講義課件
評論
0/150
提交評論