版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領
文檔簡介
STYLEREFbt1a項目十STYLEREFbt1b訪問數(shù)據(jù)庫項目十訪問數(shù)據(jù)庫思政目標找對學習方法,注重前后知識的遷移,能舉一反三。鼓勵應用創(chuàng)新,引導學生融會貫通,增強實踐能力。技能目標能夠利用常用的SQL語句查詢、更新、添加和刪除記錄。能夠使用JDBC操作數(shù)據(jù)庫中的數(shù)據(jù)。項目導讀在開發(fā)應用程序的過程中,數(shù)據(jù)庫扮演著十分重要的角色,絕大多數(shù)的應用都需要使用數(shù)據(jù)庫來存儲和管理數(shù)據(jù)。JAVA提供了專門用于操作數(shù)據(jù)庫的API,即JDBC(JavaDatabaseConnectivity,Java數(shù)據(jù)庫連接),可以很容易地訪問不同的數(shù)據(jù)庫,對數(shù)據(jù)庫中的記錄實現(xiàn)查詢、修改、刪除和添加等操作。Java開發(fā)綜合實戰(zhàn)任務1SQL語法基礎任務引入小白創(chuàng)建的進銷存管理系統(tǒng)使用數(shù)組存儲商品信息,為便于后期的數(shù)據(jù)擴容和管理,他決定利用數(shù)據(jù)庫存儲、管理商品數(shù)據(jù)。為熟悉數(shù)據(jù)查詢操作,他使用SQLServer創(chuàng)建了一個存儲學生成績的數(shù)據(jù)庫performance,并創(chuàng)建了一個成績表score、錄入了數(shù)據(jù)。如果他要查詢、更新、添加或刪除數(shù)據(jù)庫中的數(shù)據(jù),可以使用什么語句呢?知識準備訪問數(shù)據(jù)庫要使用SQL語句。SQL(StructuredQueryLanguage,結(jié)構(gòu)查詢語言)是一個用于與數(shù)據(jù)庫通信的數(shù)據(jù)庫語言,是關(guān)系數(shù)據(jù)庫管理系統(tǒng)的標準語言。SQL語句主要有以下3大類,每一類語言包含或多或少的語句,使用在不同的應用程序中。數(shù)據(jù)定義語言(DDL):用于定義數(shù)據(jù)的結(jié)構(gòu),例如創(chuàng)建、修改或刪除數(shù)據(jù)庫或數(shù)據(jù)庫中的對象(如表、視圖、存儲過程、觸發(fā)器等)。數(shù)據(jù)操縱語言(DML):用于操作數(shù)據(jù)表中的數(shù)據(jù),主要包括數(shù)據(jù)的插入、刪除、更新、查找、過濾和排序等,是最常用的核心SQL語言。數(shù)據(jù)控制語言(DCL):用于分配數(shù)據(jù)庫用戶的權(quán)限。在一般的應用程序中使用較多的是數(shù)據(jù)操縱語言,可以使用CRUD概括地表示對數(shù)據(jù)庫的常見操作,即表的創(chuàng)建(Create)、數(shù)據(jù)檢索(Retrieve)、數(shù)據(jù)更新(Update)和刪除(Delete)操作。SQL語言很復雜也很龐大,因篇幅所限,本節(jié)僅簡要介紹常用的幾個數(shù)據(jù)操縱語句,更多的SQL語句讀者可以查閱相關(guān)資料。一、select語句該語句用于在數(shù)據(jù)表中檢索符合查詢條件的數(shù)據(jù)行,僅包含指定的字段。其語法格式如下:SELECT所選字段列表FROM數(shù)據(jù)表名[WHERE查詢條件表達式][ORDERBY字段名[ASC|DESC]如果要檢索數(shù)據(jù)表中的所有列,可以使用通配符(*)替代字段列表。ORDER子句用于將查詢結(jié)果集按照某個字段值進行排序,關(guān)鍵字ASC表示升序,DESC表示降序。案例——查詢成績表SQLServer數(shù)據(jù)庫performance中的score表由一群學生的成績數(shù)據(jù)組成,每一行包含四個字段,即學生姓名、數(shù)學成績、語文成績和外語成績,如圖10-1所示。圖10-1score表如果要查詢該表中數(shù)學成績在90及以上的學生名單及對應的數(shù)學成績,并將結(jié)果按降序排列,可以利用如下SQL語句:SELECTname,MathFROMscoreWHERE(Math>=90)ORDERBYMathDESC查詢的結(jié)果如圖10-2所示。圖10-2select命令查詢結(jié)果二、insert語句INSERT語句用于在一個表中插入單行或多行數(shù)據(jù),同時賦給每個列相應的值,如果這個值支持它們定義的物理順序中的所有的值,則不需要字段名。其語法格式如下:INSERT[INTO]表名或視圖名[(字段列表)]VALUES(字段值列表)例如,下面的語句在表score中插入了學生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條件表達式例如,使用以下語句,可以在表score中修改olivia的數(shù)學和英語成績:UPDATEscoreSETMath=89,English=92WHERE(name='Olivia')注意:SQL語句中的字符串應包含在單引號中。該語句執(zhí)行之后,表score如圖10-4所示。圖10-4更新記錄后的score表四、delete語句該語句用于在數(shù)據(jù)庫中刪除符合指定條件的數(shù)據(jù)行,其語法格式如下:DELETEFROM數(shù)據(jù)表名[WHERE條件表達式]如果有查詢條件,則刪除與查詢條件相符的數(shù)據(jù)行;如果沒有查詢條件,將刪除所有的記錄。例如,下面的語句刪除表score中語文成績小于90分的成績記錄:DELETEFROMscoreWHERE(Chinese<90)執(zhí)行上面的語句后,score表如圖10-5所示。圖10-5刪除記錄后的score表任務2使用JDBC訪問數(shù)據(jù)庫任務引入小白掌握了常用的查詢語句后,想利用圖形用戶界面修改數(shù)據(jù)庫中的數(shù)據(jù),但是怎樣將數(shù)據(jù)庫與Java應用程序關(guān)聯(lián)起來呢?他查看相關(guān)資料得知,JDBC為連接數(shù)據(jù)庫提供了統(tǒng)一的規(guī)范,決定采用JDBC訪問數(shù)據(jù)庫。接下來該如何在系統(tǒng)中部署JDBC,連接數(shù)據(jù)庫呢?查詢數(shù)據(jù)后怎樣輸出滿足條件的數(shù)據(jù)記錄呢?知識準備一、JDBC概述JDBC是一套用于執(zhí)行SQL語句的JavaAPI,提供了一套數(shù)據(jù)庫操作標準,可以采用相同的API實現(xiàn)對多種關(guān)系型數(shù)據(jù)庫的統(tǒng)一操作,從而提高Java程序多數(shù)據(jù)庫的可移植性。簡單來說,JDBC能完成下列三種功能:與一個數(shù)據(jù)庫建立連接向數(shù)據(jù)庫發(fā)送SQL語句處理數(shù)據(jù)庫返回的結(jié)果JDBC由兩層構(gòu)成:上層是JDBCAPI,負責在Java應用程序和JDBC驅(qū)動程序管理器之間進行通信,發(fā)送程序中的SQL語;下層是JDBC驅(qū)動程序API,負責JDBC驅(qū)動程序管理器與實際連接的數(shù)據(jù)庫的廠商驅(qū)動程序和第三方驅(qū)動程序之間進行通信,返回查詢信息或者執(zhí)行規(guī)定的操作。如果要使用JDBC訪問某種數(shù)據(jù)庫中的數(shù)據(jù),計算機上必須安裝有JDBC驅(qū)動程序。二、部署JDBC驅(qū)動程序JDBC針對每一個數(shù)據(jù)庫廠商都提供了一個JDBC驅(qū)動程序。在連接到數(shù)據(jù)庫之前,必須首先在本地計算機上安裝數(shù)據(jù)庫和JDBC驅(qū)動程序。不同版本的JDBC驅(qū)動程序?qū)RE的要求也不相同,因此部署JDBC驅(qū)動程序之前,要先選擇正確的JAR類庫文件。例如MicrosoftJDBCDriver10.2安裝包中包含三個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運行時環(huán)境(JRE)11.0,使用JRE10.0或更低版本會引發(fā)異常。mssql-jdbc-10.2.0.jre17.jar需要JavaRuntimeEnvironment(JRE)17.0,使用較低版本會引發(fā)異常。JDBC驅(qū)動程序的具體系統(tǒng)要求可參見對應數(shù)據(jù)庫的官網(wǎng)說明。由于JDBC類庫文件不是JavaSDK的一部分,因此,在下載合適的類庫文件后,應將jar類庫文件包含在用戶應用程序的環(huán)境變量classpath中。如果使用JDBCDriver10.2,應在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設置變量CLASSPATH如果在IDE中運行訪問數(shù)據(jù)庫的Java項目,需要將JDBC數(shù)據(jù)庫驅(qū)動包添加到當前項目的構(gòu)建路徑中,步驟如下。(1)在Eclipse中右擊項目名,從彈出的快捷菜單中選擇BuildPath→ConfigureBuildPath...命令。(2)在打開的對話框左側(cè)窗格中選中“JavaBuildPath”節(jié)點,然后在Libraries選項卡中選中Classpath,單擊AddLibrary...按鈕,如圖10-7所示。(3)在打開的AddLibrary對話框的庫列表框中選擇“UserLibrary”,然后單擊Next按鈕,在彈出的對話框中,依次單擊UserLibraries按鈕,New按鈕,新建一個用戶庫的名稱。(4)依次單擊OK按鈕和ApplyandClose按鈕關(guān)閉對話框。然后單擊AddExternalJARs按鈕,在打開的對話框中選擇與JRE匹配的JDBCJAR包文件(比如與JRE17匹配的mssql-jdbc-10.2.0.jre17.jar)。單擊“打開”按鈕關(guān)閉對話框,此時可以看到新建的用戶庫如圖10-8所示。圖10-7項目屬性對話框圖10-8創(chuàng)建的用戶庫(5)依次單擊ApplyandClose按鈕和Finish按鈕關(guān)閉對話框。此時在項目的屬性對話框中可以看到添加的類庫路徑,如圖10-9所示。圖10-9添加的類庫路徑(6)添加完成后,單擊ApplyandClose按鈕關(guān)閉對話框。三、連接數(shù)據(jù)庫使用JDBC數(shù)據(jù)庫驅(qū)動方式和數(shù)據(jù)庫建立連接需要經(jīng)過兩個步驟:(1)注冊JDBC驅(qū)動程序;(2)與指定數(shù)據(jù)庫建立連接。這些操作使用JDBC中的Driver接口、DriverManager類和Connection接口實現(xiàn)。1.注冊驅(qū)動程序注冊驅(qū)動程序就是將特定數(shù)據(jù)庫的驅(qū)動程序類裝載到JVM。每種數(shù)據(jù)庫的驅(qū)動程序都提供一個實現(xiàn)Driver接口的類,簡稱Driver類,是應用程序必須首先加載的類,用于向驅(qū)動程序管理器(java.sql.DriverManager類)注冊該類的實例,以便驅(qū)動程序管理器管理數(shù)據(jù)庫驅(qū)動程序。在JDBCAPI4.0之前,通常使用java.lang.Class類的靜態(tài)方法forName(className)加載要連接的數(shù)據(jù)庫驅(qū)動程序類,并將加載的類自動向DriverManager類注冊,參數(shù)為要加載的數(shù)據(jù)庫驅(qū)動程序的完整類名。如果加載失敗,則拋出ClassNotFoundException異常。例如,下面的程序段可用于檢測SQLServer數(shù)據(jù)庫驅(qū)動程序類是否成功加載。try{//加載JDBC驅(qū)動器 Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");out.println("驅(qū)動器類加載成功");}catch(ClassNotFoundExceptione){ out.println("加載驅(qū)動器類時出現(xiàn)異常");}提示:在加載驅(qū)動程序之前,應確保驅(qū)動程序已經(jīng)在Java編譯器的類路徑中,否則會拋出找不到相關(guān)類的異常信息。要在項目中添加數(shù)據(jù)庫驅(qū)動程序,可以將下載的JDBC驅(qū)動程序直接存放在Web服務目錄的WEB-INF/lib/目錄下。從JDBCAPI4.0開始,DriverManager.getConnection()方法得到了增強,可自動加載JDBC驅(qū)動程序。因此,使用驅(qū)動程序jar庫時,應用程序無需調(diào)用Class.forName方法注冊驅(qū)動程序。當前通過使用Class.forName方法加載驅(qū)動程序的現(xiàn)有應用程序仍可繼續(xù)工作,無需進行修改。2.建立連接注冊數(shù)據(jù)庫驅(qū)動程序后,JVM和數(shù)據(jù)庫之間還沒有直接聯(lián)系,需要調(diào)用DriverManager類的靜態(tài)方法getConnection()方法獲得一個數(shù)據(jù)庫連接對象,建立Java應用程序與指定數(shù)據(jù)庫之間的聯(lián)系。建立數(shù)據(jù)庫連接對象的過程涉及兩個主要API:java.sql.DriverManager類和java.sql.Connection接口。DriverManager是JDBC用于管理驅(qū)動程序的類,主要用于管理用戶程序與特定數(shù)據(jù)庫的連接。Connection接口類對象是應用程序連接數(shù)據(jù)庫的連接對象,主要作用是調(diào)用createStatement()方法創(chuàng)建語句對象。DriverManager類有如下兩個用于建立連接的靜態(tài)方法:Connectionconn=DriverManager.getConnection(URL,user,password);Connectionconn=DriverManager.getConnection(URL);URL參數(shù)是每個JDBC驅(qū)動程序?qū)S玫腏DBCURL,語法格式如下:jdbc:子協(xié)議:數(shù)據(jù)庫定位器子協(xié)議與JDBC驅(qū)動程序有關(guān),根據(jù)實際的JDBC驅(qū)動程序廠商而不同。提示:不同版本的SQLServer數(shù)據(jù)庫的子協(xié)議有所不同。SQLServer2005之前的版本為microsoft:sqlserver;而SQLServer2005及之后的版本子協(xié)議為sqlserver。數(shù)據(jù)庫定位器用于指定要與應用程序進行交互的數(shù)據(jù)庫,根據(jù)驅(qū)動程序的類型,可能包括主機名、端口和數(shù)據(jù)庫系統(tǒng)名。例如:連接SQLServer數(shù)據(jù)庫sample的URL為"jdbc:sqlserver://localhost:1433;DatabaseName=sample"。localhost(或127.0.0.1)表示本機地址,1433是SQLServer的默認端口號,sample是數(shù)據(jù)庫名稱。很多驅(qū)動程序還接受在URL末尾附加參數(shù),如數(shù)據(jù)庫賬號的用戶名和密碼,此時采用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ù)設置為空即可。由于getConnection()方法可能拋出SQLException異常,因此在程序中應捕獲異常。例如,與SQLServer數(shù)據(jù)源student建立連接的語句如下:try{Stringurl="jdbc:sqlserver://localhost:1433;DatabaseName=student";Connectioncon=DriverManager.getConnection(url,"sa","123456");}catch(SQLExceptione){ //處理異常}注意:如果數(shù)據(jù)庫表的記錄包含漢字,在建立連接時應在URL參數(shù)中附加一個characterEncoding參數(shù),值為utf-8或gb2312。四、操作數(shù)據(jù)庫與數(shù)據(jù)庫建立連接后,就可以使用JDBC提供的API與數(shù)據(jù)庫進行交互。交互的主要方式是使用SQL語句,JDBC將標準的SQL語句發(fā)送給數(shù)據(jù)庫,數(shù)據(jù)庫執(zhí)行指令并處理查詢結(jié)果,返回結(jié)果集。1.發(fā)送、執(zhí)行SQL指令向數(shù)據(jù)庫發(fā)送SQL指令需要使用Statement接口類對象聲明一個SQL語句,然后通過創(chuàng)建的數(shù)據(jù)庫連接對象調(diào)用方法createStatement()創(chuàng)建這個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查詢語句,返回單個ResultSet結(jié)果集。executeUpdate(Stringsql):常用于執(zhí)行DML和DDL語句,返回值為int型。執(zhí)行DML語句時返回受SQL語句影響的數(shù)據(jù)行數(shù);執(zhí)行DDL語句返回0。當Connection對象處于默認狀態(tài)時,所有Statement對象都是自動執(zhí)行的,也就是說,當Statement語句對象執(zhí)行SQL語句時,該SQL語句馬上提交數(shù)據(jù)庫并返回結(jié)果。如果將連接修改為手動提交的事務模式,則只有執(zhí)行commit()方法時,才會提交相應的數(shù)據(jù)庫操作。Statement對象使用完畢后,最好使用close()方法將其關(guān)閉。如果要執(zhí)行動態(tài)SQL語句,可使用PreparedStatement接口類對象,該接口繼承自Statement接口,具有Statement接口的所有方法。由于PreparedStatement實例對象保存有已被預編譯的SQL語句,因此執(zhí)行速度比Statement對象快。通過調(diào)用Connection接口對象的preparedStatement()方法可獲得PreparedStatement對象,語法格式如下:Connectionconn=DriverManager.getConnection(url,"user","password");PreparedStatementpstmt=conn.preparedStatement(Stringsql);從上面的語法格式可以看到,使用preparedStatement()方法創(chuàng)建PreparedStatement對象時,需要SQL命令字符串作為參數(shù),以實現(xiàn)SQL命令預編譯。在SQL命令中可以包含一個或多個IN參數(shù),也可以使用“?”作為占位符。在調(diào)用executeQuery()或executeUpdate()方法之前,使用如表10-1所示的setXxx()方法為占位符賦值。表10-1PreparedStatement接口常用的方法方法說明setInt(intindex,intk)將SQL命令中出現(xiàn)次序為index的參數(shù)設置為int值ksetFloat(intindex,floatk)將SQL命令中出現(xiàn)次序為index的參數(shù)設置為float值ksetLong(intindex,longk)將SQL命令中出現(xiàn)次序為index的參數(shù)設置為long值ksetDouble(intindex,doublek)將SQL命令中出現(xiàn)次序為index的參數(shù)設置為double值ksetDate(intindex,datek)將SQL命令中出現(xiàn)次序為index的參數(shù)設置為date值k續(xù)表方法說明setString(intindex,Strings)將SQL命令中出現(xiàn)次序為index的參數(shù)設置為String值ssetNull(intindex,intsqlType)將SQL命令中出現(xiàn)次序為index的參數(shù)設置為SQLNULL例如,下面的程序段利用PreparedStatement對象在score表中插入一條記錄:try{//包含4個占位符的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語句是查詢語句,將返回一個ResultSet對象存放查詢結(jié)果。ResultSet對象由按字段組織的數(shù)據(jù)行構(gòu)成,并具有指向當前數(shù)據(jù)行的游標。當獲得一個ResultSet時,游標指向第一行記錄之前的位置,一次只能看到一個數(shù)據(jù)行。通過next()方法可移動到下一個數(shù)據(jù)行,沒有下一行時返回false。獲得一行數(shù)據(jù)后,ResultSet對象可以使用如表10-2所示的getXxx()方法獲得字段值,方法的參數(shù)可以是字段的位置索引或者是字段的名稱。表10-2獲取結(jié)果集字段值的常用方法方法說明getInt(intcolumnIndex)或getInt(StringcolumnLabel)以int形式返回ResultSet對象當前數(shù)據(jù)行指定列的值。如果列值為NULL,返回0getFloat(intcolumnIndex)或getFloat(StringcolumnLabel)以float形式返回ResultSet對象當前數(shù)據(jù)行指定列的值。如果列值為NULL,返回0getDate(intcolumnIndex)或getDate(StringcolumnLabel)以date形式返回ResultSet對象當前數(shù)據(jù)行指定列的值。如果列值為NULL,返回null
續(xù)表方法說明getBoolean(intcolumnIndex)或getBoolean(StringcolumnLabel)以Boolean形式返回ResultSet對象當前數(shù)據(jù)行指定列的值。如果列值為NULL,返回nullgetString(intcolumnIndex)或getString(StringcolumnLabel)以String形式返回ResultSet對象當前數(shù)據(jù)行指定列的值。如果列值為NULL,返回null默認情況下,ResultSet的游標只能向下一行單向移動,如果要在結(jié)果集中向前移動、或顯示結(jié)果集指定的某條記錄,則需要調(diào)用數(shù)據(jù)庫連接對象的createStatement(inttype,intconcurrency)方法創(chuàng)建一個Statement對象,然后執(zhí)行SQL語句返回一個可以滾動的結(jié)果集。語法格式如下:Statementst=conn.createStatement(inttype,intconcurrency);ResultSetrs=st.executeQuery(Stringsql);其中,type的取值(如表10-3所示)決定滾動方式;concurrency取值(如表10-4所示)決定是否可以用結(jié)果集更新數(shù)據(jù)庫。表10-3參數(shù)type的取值值含義ResultSet.TYPE_FORWORD_ONLY游標只能向下移動ResultSet.TYPE_SCROLL_INSENSITIVE游標可以上下移動,數(shù)據(jù)庫變化時,當前結(jié)果集不變ResultSet.TYPE_SCROLL_SENSITIVE游標可以上下移動,數(shù)據(jù)庫變化時,當前結(jié)果集同步改變表10-4參數(shù)concurrency的取值值含義ResultSet.CONCUR_READ_ONLY不能用結(jié)果集更新數(shù)據(jù)庫中的表ResultSet.CONCUR_UPDATETABLE能用結(jié)果集更新數(shù)據(jù)庫中的表創(chuàng)建可滾動的結(jié)果集后,利用ResultSet接口提供的一些方法可以很方便地在結(jié)果集中移動游標,如表10-5所示。表10-5移動游標的常用方法方法說明first()將游標移到結(jié)果集的第一行next()將游標移到當前數(shù)據(jù)行的下一行l(wèi)ast()將游標移到結(jié)果集的最后一行beforeFirst()將游標移動到結(jié)果集的第一行之前beforeLast()將游標移動到結(jié)果集最后一行之后absolute(introw)將游標移動到參數(shù)row指定的行號。需要注意的是,如果row為負值,表示倒數(shù)的行數(shù),即absolute(-1)表示移動到最后一行在結(jié)果集中移動游標后,使用getRow()方法可以獲取游標所指行的行號,如果結(jié)果集沒有行,則返回0。使用isFirst()和isLast()方法可以分別判斷游標是否指向結(jié)果集的第一行和最后一行。注意:對數(shù)據(jù)庫進行操作時,返回的ResultSet對象與Connection對象是有緊密聯(lián)系的,如果使用close()方法關(guān)閉連接對象,ResultSet對象中的數(shù)據(jù)會即刻消失。因此,應在數(shù)據(jù)庫操作結(jié)束后關(guān)閉數(shù)據(jù)庫連接,釋放資源,包括關(guān)閉ResultSet和Statement等資源。案例——修改學生成績表本案例利用圖形用戶界面修改SQLServer數(shù)據(jù)庫performance中的學生成績表score。成績表score的初始數(shù)據(jù)行如圖10-10所示。圖10-10初始數(shù)據(jù)表(1)在Eclipse中新建一個名為StudentQuery的Java項目。然后在項目中添加一個名為StudentList的類,創(chuàng)建用戶界面,為按鈕注冊監(jiān)聽器,監(jiān)聽ActiveEvent事件,并使用匿名內(nèi)部類訪問數(shù)據(jù)庫,處理按鈕的動作事件。具體代碼如下: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,在客戶端與服務器之間發(fā)送的所有數(shù)據(jù)使用安全套接字層(SSL)加密,JDBCDriver自動信任SQLServerSSL證書 privateStringurl="jdbc:sqlserver://localhost:1433;DatabaseName=performance;encrypt=true;trustServerCertificate=true"; staticConnectionconn; //數(shù)據(jù)庫連接對象 staticPreparedStatementpst; //PreparedStatement接口類對象 staticResultSetrs=null; //結(jié)果集 publicStudentList(){ //構(gòu)造方法 setTitle("編輯成績表"); //設置窗口標題 setBounds(100,100,370,300); //窗口大小 setResizable(false); //不可改變大小 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //關(guān)閉模式 init(); //調(diào)用成員方法初始化圖形用戶界面 } voidinit(){ content=this.getContentPane(); //獲取容器 content.setLayout(null); //使用絕對定位進行布局 //實例化三個按鈕 insertBtn=newJButton("插入記錄"); modifyBtn=newJButton("修改記錄"); deleteBtn=newJButton("刪除記錄"); //設置按鈕位置和大小 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對象 //為各個占位符賦值 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,"插入失敗,請確保學生姓名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,"修改失敗,請確保學生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("刪除學生Susie的成績!\n"); JOptionPane.showMessageDialog(null,"刪除成功!"); close(rs,conn,pst); }catch(Exceptione3){ e3.printStackTrace(); JOptionPane.showMessageDialog(null,"刪除失敗,請確保學生Susie存在!"); } } }); content.add(deleteBtn); //將按鈕添加到容器中 show=newJTextArea(); //實例化文本區(qū)域 roll=newJScrollPane(show); //為文本區(qū)域添加滾動條 roll.setBounds(5,50,340,200); //設置滾動面板的位置和大小 //設置總是顯示滾動條 roll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); content.add(roll); //將滾動面板添加到容器中 } //定義成員方法,關(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)在項目中添加一個名為TestConnection的類,添加main()方法,調(diào)用invokeLater()方法使事件派發(fā)線程上的運行對象排隊更新窗體,具體代碼如下:importjava.awt.EventQueue;publicclassTestConnection{ publicstaticvoidmain(String[]args){ //使事件派發(fā)線程(按鈕單擊事件)上的運行對象排隊,調(diào)用run()方法更新窗體組件 EventQueue.invokeLater(newRunnable(){ publicvoidrun(){ try{ StudentListframe=newStudentList(); //實例化窗體 frame.setVisible(true);//設置窗體可見性 }catch(Exceptione){ e.printStackTrace(); } } }); }}(4)在PackageExplorer窗格中右擊項目名稱,選擇BuildPath→ConfigureBuildPath...命令,將JDBC數(shù)據(jù)庫驅(qū)動包mssql-jdbc-10.2.0.jre17.jar添加到當前項目的構(gòu)建路徑中。(5)運行程序,打開如圖10-11所示的圖形用戶窗口。單擊“插入記錄”按鈕,彈出一個提示對話框,并在文本區(qū)域顯示插入的信息,如圖10-12所示。圖10-11圖形用戶界面圖10-12插入記錄(6)單擊“修改記錄”按鈕,彈出一個提示對話框,并在文本區(qū)域顯示修改的記錄信息,如圖10-13所示。(7)單擊“刪除記錄”按鈕,彈出一個提示對話框,并在文本區(qū)域顯示刪除的記錄信息,如圖10-14所示。圖10-13修改記錄圖10-14刪除記錄此時打開MicrosoftSQLServerManagementStudio,可以看到經(jīng)過以上操作后的score數(shù)據(jù)表如圖10-15所示。圖10-15操作后的數(shù)據(jù)表項目總結(jié)項目實戰(zhàn)為了便于存儲、管理入庫和出庫商品,小白決定使用JDBC+SQLServer改進、完善進銷存管理系統(tǒng)。(1)啟動SQLServerManagementStudio并登錄,新建一個名為products的數(shù)據(jù)庫,然后在數(shù)據(jù)庫中添加一個名為inbound的數(shù)據(jù)表。數(shù)據(jù)表的結(jié)構(gòu)如圖10-16所示。圖10-16設計數(shù)據(jù)表inbound(2)在Eclipse中復制并粘貼項目“進銷存管理系統(tǒng)V9.0”,在CopyProject對話框中修改項目名稱為“進銷存管理系統(tǒng)V10.0”,然后單擊Copy按鈕關(guān)閉對話框。(3)在項目中添加與JRE匹配的JDBCJAR包文件(與JRE17匹配的包文件為mssql-jdbc-10.2.0.jre17.jar)。(4)在項目中添加一個名為data的包,然后在該包中添加一個名為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)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 旅游服務合同備案辦法
- 家政服務招投標合同管理要點
- 學校大門鋼架雨棚安裝協(xié)議
- 展覽館綠化工程承包合同
- 甘肅省白銀市(2024年-2025年小學五年級語文)人教版專題練習(上學期)試卷及答案
- 四川省甘孜藏族自治州(2024年-2025年小學五年級語文)人教版期末考試(下學期)試卷及答案
- 元宵節(jié)的活動方案(15篇)
- 《債券、利率基礎知》課件
- 護理實訓小組總結(jié)匯報
- 橋梁工程施工臨時用電方案
- 四川省涼山州西昌市2023-2024學年四年級上學期期末數(shù)學試卷
- 康復護理的歷史發(fā)展
- 煙花爆竹從業(yè)人員安全培訓試題
- 電梯使用現(xiàn)場類隱患專項排查清單
- 一例下肢靜脈潰瘍患者的個案護理論文
- 危巖穩(wěn)定性計算表格-滑移式-傾倒式-墜落式-完整版
- 直播運營團隊組織架構(gòu)及崗位職責解析
- 肝膽外科運用PDCA循環(huán)縮短三四類手術(shù)患者術(shù)后留置導尿的時間
- JCT640-2010 頂進施工法用鋼筋混凝土排水管
- 注塑車間平面規(guī)劃圖OK
- 商戶洽談記錄表
評論
0/150
提交評論