版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
第10章JDBC與數(shù)據(jù)庫應(yīng)用程序開發(fā)10.1JDBC的概念與數(shù)據(jù)庫的訪問10.2JDBCAPI編程10.3JDBC應(yīng)用程序綜合實例第10章JDBC與數(shù)據(jù)庫應(yīng)用程序開發(fā)
學(xué)習(xí)目標
理解JDBC的概念,掌握使用JDBC訪問數(shù)據(jù)庫的過程;
學(xué)會使用JDBC/ODBC橋接驅(qū)動程序的方式訪問數(shù)據(jù)庫;
了解JDBCAPI中定義的主要接口的功能;
學(xué)會簡單GUI界面數(shù)據(jù)庫應(yīng)用程序的開發(fā)。在一個信息管理類應(yīng)用軟件的開發(fā)中,會使用到很多數(shù)據(jù),這些數(shù)據(jù)大多具有持久性(即需要長期保存),而使用數(shù)據(jù)庫是永久保存數(shù)據(jù)的最佳選擇。那么,在Java程序中如何使用和操作數(shù)據(jù)庫中的數(shù)據(jù)呢?由Sun公司提供的JDBC是一套基于Java技術(shù)的數(shù)據(jù)庫編程接口,它由一些操作數(shù)據(jù)庫的Java類和接口組成。用JDBC編寫訪問數(shù)據(jù)庫的程序,可以實現(xiàn)應(yīng)用程序與數(shù)據(jù)庫的無關(guān)性,即設(shè)計人員不用關(guān)心系統(tǒng)具體使用的是什么數(shù)據(jù)庫管理系統(tǒng),只要數(shù)據(jù)庫廠商提供了該數(shù)據(jù)庫的JDBC驅(qū)動程序,就可以在任何一種數(shù)據(jù)庫系統(tǒng)中使用。本章介紹JDBC的概念、工作原理和在Java程序中訪問數(shù)據(jù)庫的方法。10.1JDBC的概念與數(shù)據(jù)庫的訪問
JDBC提供了在程序中直接訪問數(shù)據(jù)庫的功能。那么,什么是JDBC?JDBC是如何工作的?本節(jié)將介紹JDBC的這些基本知識。10.1.1使用JDBC訪問數(shù)據(jù)庫
1.JDBC的概念
JDBC是一種用于執(zhí)行SQL語句的JavaAPI。JDBC本身是一個商標名而不是一個縮寫字,但JDBC常被人們認為代表“Java數(shù)據(jù)庫連接(JavaDatabaseConnectivity)”的意思。JDBC由一組用Java編程語言編寫的類和接口組成,這些類和接口完成與數(shù)據(jù)庫操作有關(guān)的各種功能,因此,數(shù)據(jù)庫開發(fā)人員可以使用JDBC來編寫數(shù)據(jù)庫應(yīng)用程序?,F(xiàn)在,JDBC已經(jīng)是Java2SDK的一個重要組成部分,JDBC中定義的類和接口都在java.sql包中。JDBCAPI的優(yōu)點是不必為訪問不同的數(shù)據(jù)庫而編寫專門的程序。也就是說,為訪問Oracle數(shù)據(jù)庫、Informix數(shù)據(jù)庫或SQLServer2000數(shù)據(jù)庫等,只需用JDBCAPI編寫一個應(yīng)用程序就可以了,而且使用Java語言編寫的應(yīng)用程序無需為不同的操作系統(tǒng)平臺編寫不同的應(yīng)用程序。因此,將Java技術(shù)和JDBC結(jié)合起來編寫訪問數(shù)據(jù)庫的Web應(yīng)用程序是一種很好的選擇。綜上所述,JDBC是一種面向?qū)ο蟮?、基于Java技術(shù)的、用于訪問數(shù)據(jù)庫的API,它由一組用Java編程語言編寫的類和接口組成,為數(shù)據(jù)庫開發(fā)人員和數(shù)據(jù)庫供應(yīng)商提供了訪問數(shù)據(jù)庫的標準。
2.?JDBC訪問數(shù)據(jù)庫的原理通常,我們所說的數(shù)據(jù)庫訪問程序,是指它可以完成以下兩種操作:●該程序能夠從數(shù)據(jù)庫中讀取數(shù)據(jù);●該程序可以將程序中的數(shù)據(jù)寫入數(shù)據(jù)庫。在Java程序中,具體訪問數(shù)據(jù)庫的過程可以用圖10-1表示。圖10-1Java程序訪問數(shù)據(jù)庫的過程從圖10-1可以看出,要使用JDBC技術(shù)訪問數(shù)據(jù)庫(如進行數(shù)據(jù)查詢)時,Java程序要通過JDBCAPI將數(shù)據(jù)庫操作語句發(fā)送給JDBC驅(qū)動程序管理器。JDBC驅(qū)動程序管理器可以以兩種方式與數(shù)據(jù)庫進行通信:一種方式是使用JDBC/ODBC橋接驅(qū)動程序間接訪問數(shù)據(jù)庫;另一種方式是使用JDBC驅(qū)動程序直接訪問數(shù)據(jù)庫。
Microsoft公司設(shè)計的開放式數(shù)據(jù)庫連接ODBCAPI,是目前廣泛應(yīng)用于Windows平臺上訪問關(guān)系數(shù)據(jù)庫的編程接口。JDBC/ODBC橋接驅(qū)動程序就是將以JDBC方式訪問數(shù)據(jù)庫的操作轉(zhuǎn)換為以O(shè)DBC訪問數(shù)據(jù)庫的方式,然后由ODBC驅(qū)動程序直接訪問數(shù)據(jù)庫。一般情況下,數(shù)據(jù)庫生產(chǎn)廠商提供的JDBC驅(qū)動程序可以直接訪問數(shù)據(jù)庫,因此這種方式簡單、高效,現(xiàn)在很多軟件開發(fā)者都使用這種方式對數(shù)據(jù)庫進行訪問。
3.使用JDBC訪問數(shù)據(jù)庫的步驟
Java程序和數(shù)據(jù)庫系統(tǒng)兩者之間并沒有什么本質(zhì)的聯(lián)系,Java程序要訪問數(shù)據(jù)庫中的數(shù)據(jù),在程序與數(shù)據(jù)庫之間就要建立所謂的“連接”,只有這個“連接”建立以后,才可以訪問數(shù)據(jù)庫。具體在一個Java程序中訪問數(shù)據(jù)庫的步驟如下:
1)裝入JDBC驅(qū)動程序在訪問數(shù)據(jù)庫前,首先要裝入某種類型的JDBC驅(qū)動程序。不同廠商的數(shù)據(jù)庫系統(tǒng),其驅(qū)動程序也不同,如IBM公司的DB2數(shù)據(jù)庫,其驅(qū)動程序是DB2Driver;微軟公司的SQLServer2000數(shù)據(jù)庫,其JDBC/ODBC橋接驅(qū)動程序是JdbcOdbcDriver。裝入JDBC驅(qū)動程序時要使用Class類的forName()方法,forName()方法的參數(shù)就是要裝入的驅(qū)動程序的名稱。Class類是java.lang包中定義的一個公共的(public)最終類(final)。Class類的實例表示運行著的Java程序中的類與接口。如要加載Oracle9i數(shù)據(jù)庫的驅(qū)動程序,可以使用如下的語句:Class.forName("oracle.jdbc.driver.OracleDriver");要加載MSSQLServer2000數(shù)據(jù)庫的驅(qū)動程序,可以使用如下的語句:Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");在調(diào)用Class.forName()方法后,會自動創(chuàng)建數(shù)據(jù)庫驅(qū)動程序的實例,并向驅(qū)動程序的管理器(DriverManager類)進行注冊。要注意的是,一般不用顯式的方法直接創(chuàng)建驅(qū)動程序的實例。在數(shù)據(jù)庫的驅(qū)動程序裝入后,就可以使用下面介紹的方法連接數(shù)據(jù)庫。
2)建立數(shù)據(jù)庫連接在給數(shù)據(jù)庫裝入驅(qū)動程序后,可以使用下列語句建立與數(shù)據(jù)庫的連接:Connectionconn=DriverManager.getConnection(URL,"用戶名","用戶密碼");數(shù)據(jù)庫連接用Connection類的一個對象表示,該類的對象使用DriverManager類的getConnecion方法獲得。其中:參數(shù)URL表示要連接數(shù)據(jù)庫的具體位置;用戶名表示登錄數(shù)據(jù)庫的用戶標識;用戶密碼表示登錄數(shù)據(jù)庫時該用戶的密碼。執(zhí)行g(shù)etConnection方法時,DriverManager類將搜索可以接受URL所代表數(shù)據(jù)庫的驅(qū)動程序(DriverManager類存有已注冊驅(qū)動程序的清單),如果找到合適的驅(qū)動程序,就從該驅(qū)動程序獲取數(shù)據(jù)庫的連接并將它返回給應(yīng)用程序。如果找不到合適的驅(qū)動程序,就無法建立與數(shù)據(jù)庫的連接,Java應(yīng)用程序便拋出一個SQLException異常。不同的JDBC驅(qū)動程序其對應(yīng)的URL也不同。?JDBCURL提供了一種確認數(shù)據(jù)庫的方法,這樣特定的數(shù)據(jù)庫驅(qū)動程序就能識別它,并與之建立連接。JDBCURL一般由三部分組成,各部分之間用冒號分隔:jdbc:子協(xié)議:子名稱各部分的含義是:●?jdbc:表示協(xié)議,JDBCURL中的協(xié)議總是jdbc?!褡訁f(xié)議:表示驅(qū)動程序名或數(shù)據(jù)庫連接機制名稱。●子名稱:根據(jù)子協(xié)議的不同而不同。在實際程序設(shè)計中,如果通過ODBC橋接方式連接本地數(shù)據(jù)庫,則URL的格式為jdbc:odbc:數(shù)據(jù)源名在這種情況下,由于ODBC已經(jīng)提供了主機、端口等信息,因此可以省略這些信息。如果使用JDBC驅(qū)動程序直接和數(shù)據(jù)庫服務(wù)器(如SQLServer2000)相連,則URL的格式為jdbc:microsoft:sqlserver://主機地址:1433當訪問本機上的數(shù)據(jù)庫時,“主機地址”為“127.0.0.1”,1433是數(shù)據(jù)庫服務(wù)器默認的偵聽端口號。如果要訪問Oracle數(shù)據(jù)庫,則URL的格式為jdbc:oracle:thin:@localhost:1521:數(shù)據(jù)庫實例名
3)執(zhí)行SQL語句在應(yīng)用程序與數(shù)據(jù)庫之間建立了連接以后,就可以用這個連接來向數(shù)據(jù)庫傳送SQL語句了。從程序中向數(shù)據(jù)庫管理系統(tǒng)發(fā)送的SQL語句有如下4種:SELCETINSERTDELETEUPDATE其實,JDBC對發(fā)送的SQL語句類型不加任何限制,這為JDBC編程提供了很好的靈活性,但程序員應(yīng)該保證SQL語句的合法性與完整性。如果發(fā)送了DBMS不能識別的SQL語句,則操作就會失敗并拋出異常。那么,在建立了數(shù)據(jù)庫連接以后,如何向數(shù)據(jù)庫發(fā)送SQL語句呢?
JDBC編程中,在發(fā)送一條SQL語句之前,必須創(chuàng)建一個Statement對象,由該對象負責(zé)向數(shù)據(jù)庫發(fā)送SQL語句。創(chuàng)建一個Statement對象時,要調(diào)用Connection接口的createStatement()方法,其一般用法是:Statementstmt=conn.createStatement();在Statement對象創(chuàng)建之后,就可以向數(shù)據(jù)庫發(fā)送SQL語句了。如果要向數(shù)據(jù)庫發(fā)送查詢語句,則可以使用Statement接口的executeQuery()方法。如下面的語句表示查詢student表中的記錄:ResultSetrs=stmt.executeQuery("SELECT*FROMstudent");
SQL語句執(zhí)行后的結(jié)果返回到ResultSet接口的一個實例中。ResultSet接口是專門用來保存SQL語句查詢結(jié)果的。在上面的語句中,查詢結(jié)果保存在rs中。如果要向數(shù)據(jù)庫發(fā)送INSERT、UPDATE或DELETE語句,就必須使用Statement接口的executeUpdate()方法。如下面是一條用INSERT插入記錄的語句:intnumberOfRows=stmt.executeUpdate("INSERTINTOtableName"+"VALUES('Tom',20)");該操作表示在表tableName中插入一行(即一個記錄),表示人名的字符串Tom要用單引號引起來,以區(qū)別于其外層的雙引號。返回的整數(shù)值numberOfRows表示受該操作影響的行數(shù)。
4)處理操作結(jié)果在使用Statement對象的executeQuery()方法執(zhí)行數(shù)據(jù)庫查詢操作時,查詢的結(jié)果集放入ResultSet對象中,該對象不但存放查詢的結(jié)果集,還提供了很多用于操作結(jié)果集的方法。在每個結(jié)果集ResultSet的對象中,有一個邏輯上的指針,通過對該指針的移動,就可以訪問到結(jié)果集中的所有數(shù)據(jù)。在開始訪問結(jié)果集時,指針總是指向結(jié)果集數(shù)據(jù)的第一條數(shù)據(jù),之后可以使用ResultSet對象的next()方法讓指針指向下一條記錄。當指針指向最后一條記錄時,如果再使用next()方法,則該方法的返回值為false,表示已經(jīng)沒有可訪問的數(shù)據(jù)了。當指針指向某條記錄時,可以使用ResultSet對象的getXXX()方法取得該數(shù)據(jù)項內(nèi)某個字段的值。在這里我們用XXX代表要取出的數(shù)據(jù)類型,如果要取出的數(shù)據(jù)類型為整型,則使用getInt方法;為實型,則使用getFloat方法。如下面的程序段可以取出結(jié)果集中的第一個字段(為int型)和第二個字段(為Float型)的值:while(rs.next()){System.out.println(rs.getInt(1));System.out.println(rs.getFloat(2));}以上的循環(huán)語句就可以將rs結(jié)果集中的記錄取出,并將第一個字段和第二個字段的值輸出。
5)關(guān)閉數(shù)據(jù)庫連接在對一個數(shù)據(jù)庫的操作完成以后,為了釋放該數(shù)據(jù)庫連接所占用的系統(tǒng)資源,應(yīng)該關(guān)閉Connection、Statement和ResultSet等對象。如要關(guān)閉上面創(chuàng)建的與數(shù)據(jù)庫操作有關(guān)的對象的程序段為:try{rs.close();stmt.close();conn.close();}catch(SQLExceptione){e.printStackTrace();}
4.?java.sql包介紹前面已經(jīng)提到,JDBCAPI被存入java.sql包中,其中包括訪問數(shù)據(jù)庫時所必需的一些類、接口和異常,其中比較重要的類與接口有:●?java.sql.DriverManager:該類用于跟蹤JDBC驅(qū)動程序,其主要功能是使用它的getConnection()方法來取得一個與數(shù)據(jù)庫的連接?!?java.sql.Driver:該接口代表JDBC驅(qū)動程序。這個接口由數(shù)據(jù)庫廠商實現(xiàn),如oracle.jdbc.OracleDriver類是Oracle數(shù)據(jù)庫提供的該接口的實現(xiàn)?!?java.sql.Connection:該接口代表與數(shù)據(jù)庫的連接,它通過DriverManager.getConnection()方法來獲得。該接口提供了創(chuàng)建SQL語句的方法,以完成SQL操作,SQL語句只能在Connection提供的環(huán)境內(nèi)部執(zhí)行?!?java.sql.Statement:該接口提供了在給定數(shù)據(jù)庫連接的環(huán)境中執(zhí)行SQL語句的方法。該接口的子接口java.sql.PreparedStstement可以執(zhí)行預(yù)先解析過的SQL語句;該接口的另外一個子接口java.sql.CallableStatement可以執(zhí)行數(shù)據(jù)庫的存儲過程?!?java.sql.ResultSet:這個接口保存了執(zhí)行數(shù)據(jù)庫的查詢語句后所產(chǎn)生的結(jié)果集,可以通過它提供的next()或absolute()等方法定位到結(jié)果集的某行?!?java.sql.SQLException:這是一個異常接口,它提供了對數(shù)據(jù)庫操作錯誤時的信息。這些接口和類的具體用法在下面介紹。10.1.2【案例10-1】使用JDBC/ODBC橋接驅(qū)動程序訪問數(shù)據(jù)庫
1.案例描述在SQLServer2000中有一個存放學(xué)生信息的數(shù)據(jù)庫students,在students數(shù)據(jù)庫中有一個存放計算機系學(xué)生信息的數(shù)據(jù)表,表名為“JSJXstuInfo”,該表的字段描述如表10-1所示。編寫一個Java程序,讀取“JSJXstuInfo”表中的數(shù)據(jù),并將數(shù)據(jù)顯示出來。表10-1表JSJXstuInfo中的字段及數(shù)據(jù)類型
2.案例效果案例程序的執(zhí)行效果如圖10-2所示。圖10-2案例10-1的顯示效果
3.技術(shù)分析使用JDBC-ODBC橋接驅(qū)動程序訪問數(shù)據(jù)庫時,首先要在Windows操作系統(tǒng)下建立DSN數(shù)據(jù)源。DSN指數(shù)據(jù)源名(DataSourceNames),由于它把數(shù)據(jù)庫、數(shù)據(jù)庫的驅(qū)動程序和一些可選設(shè)置聯(lián)系起來,用一個名稱表示,因此在配置好DSN以后訪問數(shù)據(jù)庫就比較簡單了。
DSN的配置方法如下:
1)啟動創(chuàng)建數(shù)據(jù)源的窗口在“控制面板”下找到“性能和維護”,然后打開“管理工具”窗口,在“管理工具”窗口中打開“數(shù)據(jù)源(ODBC)”。打開后的窗口名為“ODBC數(shù)據(jù)源管理器”,如圖10-3所示。圖10-3“ODBC數(shù)據(jù)源管理器”窗口
2)創(chuàng)建一個新數(shù)據(jù)源在圖10-3所示的窗口中選擇“用戶DSN”選項卡(注意在配置數(shù)據(jù)庫服務(wù)器時,要選擇“系統(tǒng)DSN”選項卡),然后單擊“添加”命令按鈕,顯示如圖10-4所示的“創(chuàng)建新數(shù)據(jù)源”窗口。在圖10-4所示的窗口中選擇“SQLServer”,然后單擊“完成”按鈕,則顯示如圖10-5所示的“建立新的數(shù)據(jù)源到SQLServer”窗口。圖10-4“創(chuàng)建新數(shù)據(jù)源”窗口圖10-5“建立新的數(shù)據(jù)源到SQLServer”窗口在圖10-5所示窗口的“名稱”文本框中輸入“students”(表示數(shù)據(jù)庫的名稱),在“服務(wù)器”下拉列表框中選擇“(local)”,然后單擊“下一步”按鈕,顯示如圖10-6所示的窗口。在圖10-6所示的窗口中可以選擇默認設(shè)置方式,然后單擊“下一步”按鈕,顯示如圖10-7所示的窗口。圖10-6用戶身份驗證窗口圖10-7選擇默認數(shù)據(jù)庫窗口在圖10-7所示的窗口中,將“更改默認的數(shù)據(jù)庫為”選中,然后在下拉列表框中選擇“students”數(shù)據(jù)庫。單擊“下一步”按鈕,顯示如圖10-8所示的窗口。在圖10-8所示的窗口中根據(jù)需要選中有關(guān)選項后,單擊“完成”按鈕,顯示如圖10-9所示的窗口。圖10-8數(shù)據(jù)庫選項窗口圖10-9數(shù)據(jù)源配置結(jié)果窗口圖10-9所示的窗口顯示新建數(shù)據(jù)源的配置信息。為了測試數(shù)據(jù)源的配置是否成功,可以單擊圖10-9中的“測試數(shù)據(jù)源”按鈕,如果顯示如圖10-10所示的窗口,則說明創(chuàng)建數(shù)據(jù)源的客戶端可以與數(shù)據(jù)庫服務(wù)器建立連接。單擊“確定”按鈕,完成配置過程。在數(shù)據(jù)源配置完成后,就可以使用本節(jié)介紹的訪問數(shù)據(jù)庫的步驟編寫程序和調(diào)試程序了。在數(shù)據(jù)源配置完成后,就可以使用本節(jié)介紹的訪問數(shù)據(jù)庫的步驟編寫程序和調(diào)試程序了。圖10-10數(shù)據(jù)源測試結(jié)果窗口
4.程序解析下面是該案例的程序代碼:01//**************************************02//案例:10-1程序名:Select.java03//功能:使用JDBC技術(shù)將數(shù)據(jù)庫中的數(shù)據(jù)讀出04//**************************************0506importjava.sql.*;07importjava.io.*;08classSelect{ 09 publicstaticvoidmain(String[]args){ 10 try {11 Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");12 Connectionconn=DriverManager.getConnection
("jdbc:odbc:students");13 Statementstmt=conn.createStatement();14 StringstrQuery="SELECT*FROMJSJXstuInfo";15 ResultSetrs=stmt.executeQuery(strQuery);16 while(rs.next()){17
System.out.print(rs.getString("stuNo"));18 System.out.print(rs.getString("stuName"));19 System.out.print(""+rs.getInt("stuAge"));20 System.out.print(""+rs.getString("stuSex"));21 System.out.println(""+rs.getString("stuClass"));22 }23 rs.close();24 stmt.close();25 conn.close();26 }27 catch(Exceptione){28 System.out.print(e);}29 }30}該案例比較簡單,它是根據(jù)本節(jié)介紹的編寫訪問數(shù)據(jù)庫程序的步驟完成的。要注意的是,訪問數(shù)據(jù)庫的程序由于數(shù)據(jù)庫或數(shù)據(jù)表可能不存在或與數(shù)據(jù)庫的連接不能正確建立等因素,往往會產(chǎn)生異常。因此,訪問數(shù)據(jù)庫的代碼要放入異常處理語句塊try中,并要在catch語句塊中進行異常處理。10.1.3【相關(guān)知識】使用JDBC修改數(shù)據(jù)表除了對數(shù)據(jù)表可以進行查詢(select)操作外,還可以使用JDBC給數(shù)據(jù)表插入記錄(insert)、刪除記錄(delete)和修改記錄(update)。
1.在數(shù)據(jù)表中插入記錄下面的程序?qū)⒃趯W(xué)生信息表JSJXstuInfo中插入一條記錄。01importjava.sql.*;02importjava.io.*;03classInsert04{05 publicstaticvoidmain(String[]args)06 { 07 try 08 { 09 Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");10 Connectionconn=DriverManager.getConnection("jdbc:odbc:students");11 Statementstmt=conn.createStatement(); 12 StringstrInsert="INSERTINTOJSJXstuInfo
VALUES('0010','任高','18','男','JSJ002')";13 introws=stmt.executeUpdate(strInsert);14 System.out.println(“在數(shù)據(jù)庫表中插入了”+rows+“行記錄");15 stmt.close();16 conn.close();17 }18 catch(Exceptione){System.out.print(e);}19 }20}在該實例中,第12行定義了要插入記錄的SQL語句,第13行使用executeUpdate方法執(zhí)行SQL插入語句,第14行顯示插入的記錄行數(shù)。
2.刪除數(shù)據(jù)表中的記錄如果將上面程序中的12、13、14行換為以下的語句,則將滿足條件的學(xué)生記錄從JSJXstuInfo表中刪除。12
StringstrDelete="DELETEFROMJSJXstuInfo
WHEREstuAge=19"; 13
introws=stmt.executeUpdate(strDelete);14
System.out.println("在數(shù)據(jù)庫表中刪除了"+rows+“行記錄");第12行定義了刪除記錄的SQL語句,第13行使用executeUpdate方法執(zhí)行SQL語句,第14行顯示刪除的行數(shù)。
3.修改數(shù)據(jù)表中的記錄如果將上面程序中的第12、13、14行換為以下的語句,則將JSJXstuInfo表中滿足條件的學(xué)生記錄進行修改:12 StringstrUpdate="UPDATEJSJXstuInfoSET
stuAge=stuAge+1"; 13 introws=stmt.executeUpdate(strUpdate);14 System.out.println("數(shù)據(jù)庫表中的"+rows+“行被修改了");第12行定義了一個修改學(xué)生記錄的SQL語句,該語句將JSJXstuInfo表中所有學(xué)生記錄的stuAge字段加1(即所有學(xué)生的年齡增加1)。由以上程序可以看出,如要修改數(shù)據(jù)表中的記錄,則需使用Statement的executeUpdate方法。10.2JDBCAPI編程上一節(jié)介紹了4種對數(shù)據(jù)表進行操作的JDBC程序,在程序中已經(jīng)使用了JDBCAPI。在對JDBCAPI有了初步了解以后,本節(jié)我們將較為詳細地介紹JDBCAPI提供的數(shù)據(jù)庫編程功能。10.2.1Connection接口
java.sql.Connection接口用來建立與數(shù)據(jù)庫的連接,該接口的實例通過DriverManager.getConnection()方法來獲得。Connection接口提供了進行事務(wù)處理、創(chuàng)建SQL語句等操作的方法。SQL語句只能在Connection提供的環(huán)境內(nèi)部執(zhí)行。該接口提供的常用方法有:●?StatementcreateStatement():創(chuàng)建執(zhí)行SQL語句的Statement對象?!?PreparedStatementprepareStatement(Stringsql):創(chuàng)建可以執(zhí)行預(yù)編譯SQL語句的PreparedStatement對象?!?CallableStatementprepareCall(String):通過創(chuàng)建一個CallableStatement對象來執(zhí)行一個SQL存儲過程調(diào)用語句?!?voidsetAutoCommit(BooleanAutoCommit):如果參數(shù)為true,則啟動自動提交功能;否則,禁止自動提交。●?DatabaseMetaDatagetMetaData():返回用于確定數(shù)據(jù)庫特性的DatabaseMetaData對象。●?voidcommit():提交對數(shù)據(jù)庫的操作?!?voidrollback():回退(即撤消)對數(shù)據(jù)庫的操作?!?voidclose():釋放對數(shù)據(jù)庫的連接。10.2.2Statement接口
Java程序與數(shù)據(jù)庫的建立連接以后,就可以使用Statement接口的對象執(zhí)行SQL語言了。Statement接口不能直接實例化一個對象,該接口的實例只能由Connection對象的createStatement()方法產(chǎn)生。該接口提供的常用方法有:●?ResultSetexecuteQuery(Stringsql):執(zhí)行一條SQL查詢語句,返回的結(jié)果保存在ResultSet對象中?!?intexecuteUpdate(Stringsql):執(zhí)行一條INSERT、UPDATE或DELETE語句,返回的結(jié)果為受SQL語句影響的行數(shù)。另外,它也可以執(zhí)行沒有返回值的SQL語句,如SQL創(chuàng)建數(shù)據(jù)表的語句,這時返回的值為0?!?voidsetMaxRows(intmaxmaxRows):用來限制ResultSet可包含的最大行數(shù)。如果超過這個限制,則超過的行將被丟棄?!?voidgetMaxRows():返回記錄集中當前包含的最大行數(shù)。下面的實例使用executeUpdate(Stringsql)方法創(chuàng)建一個名為JSJXstuScore的數(shù)據(jù)表。該表有兩個字段:“stuNo”字段,用來存儲學(xué)號;“java”字段,用來存儲該學(xué)生的成績。01importjava.sql.*;02importjava.io.*;03classCreateTable{ 04 publicstaticvoidmain(String[]args){ 05 try {06 Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");07 Connectionconn=DriverManager.getConnection
("jdbc:odbc:students");08 Statementstmt=conn.createStatement();09 StringstrCreate="CREATETABLEJSJXstuScore
(stuNochar(6),javaint)"; 10 stmt.executeUpdate(strCreate);11 System.out.println("創(chuàng)建了一個數(shù)據(jù)庫表"); 12 stmt.close();13 conn.close();14 }15 catch(Exceptione){System.out.print(e);} 16}17}該實例的09行定義了一條創(chuàng)建數(shù)據(jù)表的SQL語句,第10行調(diào)用Statement對象的executeUpdate方法執(zhí)行該語句。該程序正確執(zhí)行后,將在Students數(shù)據(jù)庫中創(chuàng)建一個名為JSJXstuScore的數(shù)據(jù)表。10.2.3PreparedStatement接口如果一條SQL語句需要被執(zhí)行多次,則當使用Statement對象時,每次都要將該SQL語句傳遞給數(shù)據(jù)庫管理系統(tǒng)DBMS,這會嚴重影響SQL語句的執(zhí)行效率。為此,可以使用Statement接口的子接口PreparedStatement,它的實例包含了已編譯的SQL語句。已編譯的SQL語句是指當一條SQL語句傳到DBMS時,由DBMS對SQL語句進行編譯和優(yōu)化,并將編譯后的SQL語句保存在緩存中。這樣以后執(zhí)行該語句時,可以從緩存中直接取出該SQL語句進行執(zhí)行,提高了SQL語句執(zhí)行的效率。包含于PreparedStatement對象中的SQL語句可有一個或多個參數(shù),因為參數(shù)用于提供數(shù)據(jù)(即輸入),所以稱為IN參數(shù)(即輸入?yún)?shù))。IN參數(shù)的值在SQL語句創(chuàng)建時未被指定,該語句為每個IN參數(shù)保留一個問號(“?”)作為占位符。每個問號的值必須在該語句執(zhí)行之前,通過適當?shù)膕etXXX方法來提供。作為Statement的子接口,PreparedStatement繼承了Statement的所有功能。另外,它還添加了一整套方法,這些方法用于設(shè)置發(fā)送給數(shù)據(jù)庫以取代SQL語句中IN參數(shù)占位符的值。同時,PreparedStatement接口提供的方法executeQuery和executeUpdate不再需要參數(shù)。
1.創(chuàng)建PreparedStatement對象同Statement對象類似,PreparedStatement對象只能使用Connection對象的prepareStatement方法獲得。下面的語句(其中conn屬于Connection類型)創(chuàng)建了一個PreparedStatement對象,該對象是含有兩個IN參數(shù)占位符的SQL語句:PreparedStatementpstmt=conn.prepareStatement("INSERTINTOJSJXstuScoreVALUES(?,?)");
pstmt對象包含的INSERT語句中有兩個參數(shù),要求在執(zhí)行時給這兩個參數(shù)提供數(shù)值,即為IN參數(shù)提供具體的數(shù)據(jù)。
2.設(shè)置IN參數(shù)的值在執(zhí)行PreparedStatement對象之前,必須設(shè)置每個“?”參數(shù)的值。這可通過調(diào)用PreparedStatement對象的setXXX方法來完成,其中XXX代表與該參數(shù)類型相匹配的數(shù)據(jù)類型。例如,如果參數(shù)是Java中的long類型,則使用的方法就是setLong。setXXX方法的第一個參數(shù)是要設(shè)置的參數(shù)的序數(shù)位置,第二個參數(shù)設(shè)置該參數(shù)的值。例如,以下代碼將第一個參數(shù)設(shè)為"00023",第二個參數(shù)設(shè)置為89:pstmt.setString(1,"00023");pstmt.setInt(2,89);一旦設(shè)置了給定語句的IN參數(shù)值,就可多次執(zhí)行該語句,直到調(diào)用PreparedStatement對象的clearParameters方法清除參數(shù)值為止。下面是一個PreparedStatement對象執(zhí)行SQL語句的實例程序,該程序使用PreparedStatement對象在數(shù)據(jù)表JSJXstuScore中插入10條記錄。01importjava.sql.*;02importjava.io.*;03classPreparedInsert{ 04 publicstaticvoidmain(String[]args){05 int[]score={67,78,45,78,67,98,97,77,67,87};06 introwCount;07 try {08 Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");09 Connectionconn=DriverManager.getConnection
("jdbc:odbc:students");10 StringstrInsert="INSERTINTOJSJXstuScore
VALUES(?,?)";11 PreparedStatementpstmt=conn.prepareStatement
(strInsert);12 for(inti=0;i<10;i++){13 pstmt.setString(1,String.valueOf(i));14 pstmt.setInt(2,score[i]);15 rowCount=pstmt.executeUpdate();16 }17 pstmt.close();18 conn.close();19 }20 catch(Exceptione){System.out.print(e);}21 }22}該實例的05行定義了一個存放學(xué)生成績的數(shù)組。10行定義了一條插入記錄的SQL語句。11行調(diào)用Connection對象的prepareStatement()方法生成一個PreparedStatement的實例。12~16行利用循環(huán)語句在數(shù)據(jù)表JSJXstuScore中插入10條記錄。13行調(diào)用PreparedStatement的setString方法給JSJXstuScore表的第一個字段設(shè)置一個字符串值,其中的String.valueOf函數(shù)可以將一個整數(shù)轉(zhuǎn)化為字符串。14行調(diào)用PreparedStatement的setInt方法給JSJXstuScore表的第二個字段設(shè)置成績,成績存放在score數(shù)組中。10.2.4CallableStatement接口
CallableStatement接口是PreparedStatement接口的子接口,因此它具有Statement接口和PreparedStatement接口所提供的功能。該接口的實例對象為所有的DBMS提供了一種以標準形式調(diào)用儲存過程的方法。在JDBC中,調(diào)用儲存過程的語法如下:{call過程名[(?,?,...)]}當儲存過程返回一個結(jié)果參數(shù)時,使用如下的格式:{?=call過程名[(?,?,...)]}一個不帶參數(shù)、不返回結(jié)果的儲存過程,可以使用如下的格式調(diào)用:{call過程名}注意:方括號表示其中的內(nèi)容是可選項,方括號本身并不是語法的組成部分。
1.創(chuàng)建CallableStatement對象儲存過程保存在數(shù)據(jù)庫中,通過CallableStatement對象就可以調(diào)用一個儲存過程。因為CallableStatement是一個接口,所以不能直接實例化一個該類的對象。CallableStatement實例對象要使用Connection對象的prepareCall(Stringsql)方法取得。如一個儲存過程名為getTestData,它有兩個參數(shù),可以使用如下的格式生成CallableStatement對象:CallableStatementcstmt=conn.prepareCall("{callgetTestData(?,?)}");其中,?為占位符。?代表的參數(shù)可能是輸入?yún)?shù)(IN),也可能是輸出參數(shù)(OUT),還有可能既是輸入?yún)?shù)又是輸出參數(shù)(INOUT),這取決于儲存過程getTestData。通常,創(chuàng)建CallableStatement對象時應(yīng)當知道所用的DBMS是否支持儲存過程。如果需要檢查DBMS是否支持儲存過程,則可以使用DatabaseMetaData對象的supportsStoredProcedures方法進行測試,如果其返回值為true,則表示該DBMS支持儲存過程。
2.?IN和OUT參數(shù)將IN參數(shù)傳給CallableStatement對象是通過setXXX方法完成的。該方法繼承自PreparedStatement接口,所傳入?yún)?shù)的類型決定了所用的setXXX方法(例如,用setFloat來傳入float值等)。如果儲存過程返回OUT參數(shù),則在執(zhí)行CallableStatement對象以前必須先注冊每個OUT參數(shù)的JDBC類型(這是必需的,因為某些DBMS要求知道JDBC類型)。注冊JDBC類型是用registerOutParameter方法來完成的。在語句執(zhí)行完后,可以使用CallableStatement的getXXX方法取回參數(shù)值。registerOutParameter使用的是JDBC類型(因此它與數(shù)據(jù)庫返回的JDBC類型匹配),而getXXX可將之轉(zhuǎn)換為Java類型。下面是一個使用輸出參數(shù)的實例:CallableStatementcstmt=conn.prepareCall("{callgetTestData(?,?)}");cstmt.registerOutParameter(1,java.sql.Types.TINYINT);cstmt.registerOutParameter(2,java.sql.Types.DECIMAL,3);cstmt.executeQuery();bytex=cstmt.getByte(1);java.math.BigDecimaln=cstmt.getBigDecimal(2,3);第2行和第3行代碼先注冊了OUT參數(shù)的類型。注意,注冊的是JDBC中的數(shù)據(jù)類型。第4行執(zhí)行由cstmt所調(diào)用的儲存過程,第5行和第6行取得在OUT參數(shù)中返回的值。方法getByte從第一個OUT參數(shù)中取出一個Java字節(jié)型數(shù)據(jù),而getBigDecimal從第二個OUT參數(shù)中取出一個BigDecimal對象(小數(shù)點后面帶三位數(shù))。
3.?INOUT參數(shù)既支持輸入又支持輸出的參數(shù)即為INOUT參數(shù)。INOUT參數(shù)除了要調(diào)用registerOutParameter方法外,還要求調(diào)用適當?shù)膕etXXX方法(該方法是從PreparedStatement繼承來的)。?setXXX方法將參數(shù)值設(shè)置為輸入?yún)?shù),?而registerOutParameter方法將它的JDBC類型注冊為輸出參數(shù)。setXXX方法提供一個Java值,而驅(qū)動程序先把這個值轉(zhuǎn)換為JDBC值,然后將它送到數(shù)據(jù)庫中。這種IN值的JDBC類型和提供給registerOutParameter方法的JDBC類型應(yīng)該相同。要檢索輸出值,就要用對應(yīng)的getXXX方法。例如,Java的類型為byte的參數(shù)應(yīng)該使用方法setByte來賦輸入值。而應(yīng)該給registerOutParameter方法提供的類型為TINYINT(JDBC類型),同時應(yīng)使用getByte來取得輸出值。下面是一個使用輸入/輸出參數(shù)(INOUT)的實例:CallableStatementcstmt=conn.prepareCall("{callreviseTotal(?)}");cstmt.setByte(1,25);cstmt.registerOutParameter(1,java.sql.Types.TINYINT);cstmt.executeUpdate();bytex=cstmt.getByte(1);上面的代碼中,要調(diào)用的存儲過程名為reviseTotal,它只有一個參數(shù),該參數(shù)是INOUT參數(shù)。第2行的setByte方法把此參數(shù)的輸入值設(shè)為25,驅(qū)動程序?qū)阉鳛镴DBCTINYINT類型送到數(shù)據(jù)庫中。第3行的注冊語句registerOutParameter將該參數(shù)注冊為JDBCTINYINT類型。第4行執(zhí)行完該儲存過程后,將返回一個新的JDBCTINYINT值。第5行的方法getByte將把這個新值作為Javabyte類型取得后存入變量x中。10.2.5ResultSet接口
ResultSet接口包含符合查詢條件的記錄的結(jié)果集。這個結(jié)果集可以看成是一個二維表格,它由若干行組成,其中有查詢所返回的列標題及相應(yīng)的值。通過一套getXXX方法就可以訪問當前行中不同列的值。要訪問結(jié)果集中的數(shù)據(jù),首先要找到數(shù)據(jù)所在的行,然后才能取得該行某列的數(shù)據(jù)。完成這樣的操作要依靠一個指向當前行的指針。在開始時,指針指向第一行之前的位置,調(diào)用ResultSet的next方法可將指針移動到結(jié)果集的下一行,使下一行成為當前行。如果指針被移到了結(jié)果集的最后一行的下面,則next方法返回false。具體應(yīng)用見案例10-1。對于取得列數(shù)據(jù)的getXXX方法,JDBC驅(qū)動程序試圖將基本數(shù)據(jù)轉(zhuǎn)換成指定的Java類型,然后返回適合的Java值。例如,如果getXXX方法為getString,而基本數(shù)據(jù)庫中的數(shù)據(jù)類型為VARCHAR,則JDBC驅(qū)動程序?qū)裋ARCHAR類型轉(zhuǎn)換成Java中的String類型,這樣,getString的返回值將為Java中的String對象。
ResultSet中返回Java對象的getXXX方法有g(shù)etString、getDate、getTime、getTimestamp、getObject等。ResultSet中返回數(shù)值的getXXX方法有g(shù)etByte、getShort、getInt、getLong、getFloat和getDouble。ResultSet中返回布爾值的方法是getBoolean。
getXXX方法返回的Java數(shù)據(jù)類型與SQL類型的對應(yīng)關(guān)系如表10-2。表10-2Java數(shù)據(jù)類型與SQL類型的對應(yīng)關(guān)系10.2.6ResultSetMetaData接口
ResultSetMetaData對象可用于查找ResultSet結(jié)果集中列的類型和特性。在編程時,ResultSetMetaData對象使用ResultSet對象的getMetaData()方法來取得。例如:ResultSetrs=stmt.executeQuery("SELECTa,b,cFROMTABLE2");ResultSetMetaDatarsmd=rs.getMetaData();intnumberOfColumns=rsmd.getColumnCount();…
ResultSetMetaData接口提供的常用方法如下:●?intgetColumnCount():獲得ResultSet中的列數(shù)?!?booleanisCaseSensitive(intcolumn):列是否區(qū)分大小寫。●?booleanisSearchable(intcolumn):該列能否用于WHERE子句?!?intisNullable(intcolumn):在該列中是否可以放一個NULL值?!?StringgetColumnLabel(intcolumn):獲得用于打印輸出和顯示的建議列標題?!?StringgetColumnName(intcolumn):獲得列名?!?intgetScale(intcolumn):獲得一個列的十進制小數(shù)點右面數(shù)字的位數(shù)?!?StringgetTableName(intcolumn):獲得列的表名?!?StringgetCatalogName(intcolumn):獲得列所在表的目錄名?!?intgetColumnType(intcolumn):獲得一個列的SQL類型?!?booleanisReadOnly(intcolumn):列是否是只讀的。技能拓展10.3JDBC應(yīng)用程序綜合實例在各種管理程序中,數(shù)據(jù)一般都保存在數(shù)據(jù)庫中,應(yīng)用程序一般使用圖形用戶界面對數(shù)據(jù)庫中的數(shù)據(jù)進行修改、插入和刪除等。本節(jié)以一個實例說明這類程序的設(shè)計方法。10.3.1實例描述設(shè)計一個管理學(xué)生信息的程序,可以對學(xué)生信息進行瀏覽、修改、刪除和插入操作。學(xué)生的信息由學(xué)號、姓名、性別、出生日期、系別、專業(yè)、班級和個人簡歷組成。在SQLServer2000下建立一個學(xué)生(students)數(shù)據(jù)庫,在該數(shù)據(jù)庫中建立一個如表10-3所示的學(xué)生信息表。表10-3學(xué)生信息表10.3.2程序運行結(jié)果該程序的運行結(jié)果如圖10-11所示。圖10-11(a)是學(xué)生的“個人信息”選項卡,圖10-11(b)是學(xué)生的“個人簡歷”選項卡。該程序界面的上部有4個工具按鈕:“修改”、“刪除”、“添加”和“退出”。在窗口的下部有4個瀏覽按鈕,用來選擇窗口中顯示的學(xué)生記錄:第一個按鈕表示顯示“第一條學(xué)生記錄”,第二個按鈕表示顯示當前學(xué)生記錄的“前一條學(xué)生記錄”,第三個按鈕表示顯示當前記錄的“后一條學(xué)生記錄”,第四個按鈕表示顯示“最后一條學(xué)生記錄”。圖10-11學(xué)生信息管理程序運行結(jié)果(a)圖10-11學(xué)生信息管理程序運行結(jié)果(b)10.3.3程序設(shè)計
1.定義學(xué)生類該程序要對學(xué)生信息進行處理,所以在程序中要定義一個學(xué)生類。學(xué)生類的定義如下:01//********************************************02//案例:10-2程序名:Student.java03//功能:定義學(xué)生類04//********************************************05packagestudents;0607publicclassStudent{08 privateStringstuNo;//學(xué)號09 privateStringstuName;//姓名10 privateStringstuSex;//性別11 privateStringstuBirthday;//出生日期12 privateStringstuDepartment;//系別13 privateStringstuSpeciality;//專業(yè)14 privateStringstuClass;//班級15 privateStringstuHistory;//簡歷16 17 //無參構(gòu)造方法18 publicStudent(){}19 20 publicStringgetStuNo(){returnstuNo;}21 publicvoidsetStuNo(StringstuNo){22 this.stuNo=stuNo;23 }24 25 publicStringgetStuName(){returnstuName;}26 publicvoidsetStuName(StringstuName){27 this.stuName=stuName;28 }29 30 publicStringgetStuSex(){returnstuSex;}31 publicvoidsetStuSex(StringstuSex){32 this.stuSex=stuSex;33 }34 35 publicStringgetStuBirthday(){returnstuBirthday;}36 publicvoidsetStuBirthday(StringstuBirthday){37 this.stuBirthday=stuBirthday;38 }39 40 publicStringgetStuDepartment(){returnstuDepartment;}41 publicvoidsetStuDepartment(StringstuDepartment){42 this.stuDepartment=stuDepartment;43 }44 45 publicStringgetStuSpeciality(){returnstuSpeciality;}46 publicvoidsetStuSpeciality(StringstuSpeciality){47 this.stuSpeciality=stuSpeciality;48 }49 50 publicStringgetStuClass(){returnstuClass;}51 publicvoidsetStuClass(StringstuClass){52 this.stuClass=stuClass;53 }54 55 publicStringgetStuHistory(){returnstuHistory;}56 publicvoidsetStuHistory(StringstuHistory){57 this.stuHistory=stuHistory;58 }59}學(xué)生類的每個屬性定義了一個設(shè)置屬性的方法(setXxx)和一個獲取學(xué)生屬性的方法(getXxx)。第05行表明將定義的學(xué)生類放入students包中。用下列命令編譯該類:javac-dStudent.java
2.定義從數(shù)據(jù)庫中讀取學(xué)生記錄的類在GUI界面中要顯示、修改、插入和刪除學(xué)生記錄,因此,程序中專門定義了一個存取學(xué)生信息的類,該類中定義了一些處理學(xué)生記錄的靜態(tài)方法。程序如下:001//**********************************************002//案例:10-2程序名:StudentDBA.java003//功能:定義存取數(shù)據(jù)庫的類004//**********************************************005006packagestudents;007008importjava.sql.*;009importjava.util.ArrayList;010importjavax.swing.*;011012publicclassStudentDBA{013 014 privatestaticArrayListstudents=newArrayList();
//存放讀取的學(xué)生記錄015 privatestaticConnectionconn=null;016 privatestaticStatementstatement=null;017 privatestaticResultSetrs=null;018 privatestaticintloc=0;019 020 privatestaticvoidgetDBConnection(){021 try{022 Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");023 Connectionconn=DriverManager.getConnection
("jdbc:odbc:students");024 }025 catch(ClassNotFoundExceptione1){
JOptionPane.showMessageDialog(null,“找不到數(shù)據(jù)庫驅(qū)動程序類!\n”+e1,“提示”,
JOptionPane.ERROR_MESSAGE);027 }028 catch(SQLExceptione2){029 JOptionPane.showMessageDialog(null,“無法連接數(shù)據(jù)庫!\n"+e2,"提示",JOptionPane.
ERROR_MESSAGE);030 }031 }032 033 publicstaticArrayListgetAllStudents(){034 StringstrSQL="SELECT*FROMStudent";035 students.clear();036 try{037 getDBConnection();038 statement=conn.createStatement();039 rs=statement.executeQuery(strSQL);040 while(rs.next()){041 Studentstu=newStudent();042 stu.setStuNo(rs.getString(1));043 stu.setStuName(rs.getString(2));044 stu.setStuSex(rs.getString(3));045 stu.setStuBirthday(String.valueOf(rs.getDate(4)));046 stu.setStuDepartment(rs.getString(5));047 stu.setStuSpeciality(rs.getString(6));048 stu.setStuClass(rs.getString(7));049 stu.setStuHistory(rs.getString(8));050 students.add(stu);051 }052 }053 catch(SQLExceptione){054 JOptionPane.showMessageDialog
(null,"無法連接數(shù)據(jù)庫!\n"+e,"提示",
JoptionPane.ERROR_MESSAGE);055 }056 finally{057 close();058 }059 returnstudents;060 }061 062 publicstaticStudentgetCurrentStudent(){063 if(students.size()>0)064 return(Student)students.get(loc);065 elsereturnnull;066 }067 068 publicstaticStudentgetNextStudent(){loc++;070 if(loc<students.size())071 return(Student)students.get(loc);072 else{073 loc--;074 return(Student)students.get(loc);}076 }077 078 publicstaticStudentgetPrevStudent(){079 loc--;080 if(loc>=0)081 return(Student)students.get(loc);082 else{083 loc++;084 return(Student)students.get(loc);085 }086 }087 088 publicstaticStudentgetFirstStudent(){089 Students=newStudent();090 if(students.size()>0){091 loc=0;092 s=(Student)students.get(loc);093 }094 returns;095 }096 097 publicstaticStudentgetLastStudent(){098 if(students.size()>0){099 loc=students.size()-1;100 return(Student)students.get(loc);101 }102 else returnnull;103}104105publicstaticvoidaddStudent(Students){106 StringstrSQL="INSERTINTOstudentVALUES(";107 strSQL+="'"+s.getStuNo()+"'"+",";108 strSQL+="'"+s.getStuName()+"'"+",";109 strSQL+="'"+s.getStuSex()+"'"+",";110 strSQL+="'"+s.getStuBirthday()+"'"+",";111 strSQL+="'"+s.getStuDepartment()+"'"+",";112 strSQL+="'"+s.getStuSpeciality()+"'"+",";113 strSQL+="'"+s.getStuClass()+"'"+",";114 strSQL+="'"+s.getStuHistory()+"'"+")";115 try{116 getDBConnection();117 statement=conn.createStatement();118 statement.executeUpdate(strSQL);119 loc=students.size()-1;120 JOptionPane.showMessageDialog
(null,"記錄被正確插入!");121 122 }123 catch(SQLExceptione){124 JOptionPane.showMessageDialog(null,“插入數(shù)據(jù)發(fā)生錯誤!\n”+e,“錯誤”,
JOptionPane.ERROR_MESSAGE);125 }126 finally{127 close();128 }129}130 131publicstaticvoiddeleteStudent(){132 Students=getCurrentStudent();133 StringstrSQL="DELETEFROMstudentWHERE
stuNo='"+s.getStuNo()+"'";134 try{135 getDBConnection();136 statement=conn.createStatement();137 intn=statement.executeUpdate(strSQL);138 JOptionPane.showMessageDialog(null,n+“行被刪除!
");139 if(loc>0)140 loc--;141 }142 catch(SQLExceptione){143 JOptionPane.showMessageDialog(null,“數(shù)據(jù)刪除發(fā)生錯誤!\n“+e,”錯誤“,JOptionPane.
ERROR_MESSAGE);144 }145 finally{146 close();147 }148}149150publicstaticvoidupdateStudent(Students){151 StringstrSQL="UPDATEstudentSET";152 strSQL+="stuName="+"'"+s.getStuName()+"',";153 strSQL+="stuSex="+"'"+s.getStuSex()+"'
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 14《天文學(xué)上的曠世之爭》說課稿 2023-2024學(xué)年統(tǒng)編版高中語文選擇性必修下冊
- 2025年度智能云計算平臺運維服務(wù)合同2篇
- 2025年度新能源出租車司機勞動合同規(guī)范范本2篇
- 福建省南平市太平中學(xué)高一化學(xué)模擬試題含解析
- 福建省南平市松溪縣第二中學(xué)高一地理模擬試題含解析
- 2024年版:廣告發(fā)布合同廣告內(nèi)容審核與責(zé)任分配
- 2024版二手房租賃買賣合同范本
- 農(nóng)場年度榮耀
- 2025版智能家居配套大平方樓房買賣合同3篇
- 大V賬號推廣合同(2篇)
- 部編版語文三年級下冊第二單元整體作業(yè)設(shè)計
- ISO 56001-2024《創(chuàng)新管理體系-要求》專業(yè)解讀與應(yīng)用實踐指導(dǎo)材料之11:“5領(lǐng)導(dǎo)作用-5.5崗位、職責(zé)和權(quán)限”(雷澤佳編制-2025B0)
- 物聯(lián)網(wǎng)安全風(fēng)險評估剖析-洞察分析
- 2024年-江西省安全員C證考試題庫
- 物業(yè)保安培訓(xùn)工作計劃
- 開題報告課件(最終)
- 治未病科室建設(shè)
- 投標部述職報告
- 2024天津高考英語試題及答案
- 中國高鐵技術(shù)的發(fā)展與展望
- 2014-2024年高考語文真題匯編之詩歌鑒賞含答案解析
評論
0/150
提交評論