




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第2章JDBC數(shù)據(jù)庫(kù)編程1.1JDBC概述1.2數(shù)據(jù)庫(kù)基本操作1.3數(shù)據(jù)庫(kù)存取優(yōu)化習(xí)題
2.1JDBC概述2.1.1JDBC數(shù)據(jù)庫(kù)應(yīng)用模型
JDBC由兩層構(gòu)成,一層是JDBCAPI,負(fù)責(zé)在Java應(yīng)用程序與JDBC驅(qū)動(dòng)程序管理器之間進(jìn)行通信,負(fù)責(zé)發(fā)送程序中的SQL語(yǔ)句。其下一層是JDBC驅(qū)動(dòng)程序API,與實(shí)際連接數(shù)據(jù)庫(kù)的第三方驅(qū)動(dòng)程序進(jìn)行通信,返回查詢信息或者執(zhí)行規(guī)定的操作。如圖所示。
1.Java應(yīng)用程序
Java程序包括應(yīng)用程序、Applet以及Servlet,這些類型的程序都可以利用JDBC實(shí)現(xiàn)對(duì)數(shù)據(jù)庫(kù)的訪問(wèn),JDBC在其中所起的作用包括:請(qǐng)求與數(shù)據(jù)庫(kù)建立連接、向數(shù)據(jù)庫(kù)發(fā)送SQL請(qǐng)求、處理查詢、錯(cuò)誤處理等操作。
2.JDBC驅(qū)動(dòng)程序管理器
JDBC驅(qū)動(dòng)程序管理器動(dòng)態(tài)地管理和維護(hù)數(shù)據(jù)庫(kù)查詢所需要的驅(qū)動(dòng)程序?qū)ο?,?shí)現(xiàn)Java程序與特定驅(qū)動(dòng)程序的連接。它完成的主要任務(wù)包括:為特定的數(shù)據(jù)庫(kù)選取驅(qū)動(dòng)程序、處理JDBC初始化調(diào)用、為每個(gè)驅(qū)動(dòng)程序提供JDBC功能的入口、為JDBC調(diào)用傳遞參數(shù)等。3.驅(qū)動(dòng)程序驅(qū)動(dòng)程序一般由數(shù)據(jù)庫(kù)廠商或者第三方提供,由JDBC方法調(diào)用,向特定數(shù)據(jù)庫(kù)發(fā)送SQL請(qǐng)求,并為程序獲取結(jié)果。驅(qū)動(dòng)程序完成下列的任務(wù):建立與數(shù)據(jù)庫(kù)的連接、向數(shù)據(jù)庫(kù)發(fā)送請(qǐng)求、在用戶程序請(qǐng)求時(shí)進(jìn)行翻譯、錯(cuò)誤處理。4.?dāng)?shù)據(jù)庫(kù)數(shù)據(jù)庫(kù)指數(shù)據(jù)庫(kù)管理系統(tǒng)和用戶程序所需要的數(shù)據(jù)庫(kù)。2.1.2JDBC驅(qū)動(dòng)程序JDBC驅(qū)動(dòng)程序分為以下四種類型。(1)類型1,JDBC-ODBCBridgeDriver,這種驅(qū)動(dòng)方式通過(guò)ODBC驅(qū)動(dòng)器提供數(shù)據(jù)庫(kù)連接。使用這種方式要求客戶機(jī)裝入ODBC驅(qū)動(dòng)程序。(2)類型2,Native-APIpartly-JavaDriver,這種驅(qū)動(dòng)方式將數(shù)據(jù)庫(kù)廠商所提供的特殊協(xié)議轉(zhuǎn)換為Java代碼及二進(jìn)制代碼,利用客戶機(jī)上的本地代碼庫(kù)與數(shù)據(jù)庫(kù)進(jìn)行直接通信。和類型1一樣,這種驅(qū)動(dòng)方式也存在很多局限,由于使用本地庫(kù),因此,必須將這些庫(kù)預(yù)先安裝在客戶機(jī)上。(3)類型3,JDBC-NetAll-JavaDriver,這種類型的驅(qū)動(dòng)程序是純Java代碼的驅(qū)動(dòng)程序,它將JDBC指令轉(zhuǎn)換成獨(dú)立于DBMS的網(wǎng)絡(luò)協(xié)議形式并與某種中間層連接,再通過(guò)中間層與特定的數(shù)據(jù)庫(kù)通信。該類型驅(qū)動(dòng)具有最大的靈活性,通常由非數(shù)據(jù)庫(kù)廠商提供,是四種類型中最小的。(4)類型4,Native-protocolAll-JavaDriver,這種驅(qū)動(dòng)程序也是一種純Java的驅(qū)動(dòng)程序,它通過(guò)本地協(xié)議直接與數(shù)據(jù)庫(kù)引擎相連接。這種驅(qū)動(dòng)程序也能應(yīng)用于Internet。在全部四種驅(qū)動(dòng)方式中,這種方式具有最好的性能。2.1.3用JDBC訪問(wèn)數(shù)據(jù)庫(kù)用JDBC實(shí)現(xiàn)訪問(wèn)數(shù)據(jù)庫(kù)要經(jīng)歷以下幾個(gè)步驟:1.建立數(shù)據(jù)源這里的數(shù)據(jù)源是指ODBC數(shù)據(jù)源,這一點(diǎn)不是JDBC所必需的,而是當(dāng)使用驅(qū)動(dòng)程序類型1即JDBC-ODBCBridge建立連接時(shí)所需要的步驟。2.裝入JDBC驅(qū)動(dòng)程序
DriverManager類管理各種數(shù)據(jù)庫(kù)驅(qū)動(dòng)程序,建立新的數(shù)據(jù)庫(kù)連接。
JDBC驅(qū)動(dòng)程序通過(guò)調(diào)用registerDriver方法進(jìn)行注冊(cè)。用戶在正常情況下不會(huì)直接調(diào)用DriverManager.registerDriver,而是在加載驅(qū)動(dòng)程序時(shí)由驅(qū)動(dòng)程序自動(dòng)調(diào)用。加載Driver類,自動(dòng)在DriverManager中注冊(cè)的方法有以下兩種:(1)調(diào)用方法Class.forName()將顯式地加載驅(qū)動(dòng)程序類。例如加載Sybase數(shù)據(jù)庫(kù)驅(qū)動(dòng)程序:
Class.forName(“com.sybase.jdbc2.jdbc.SybDriver”);(2)通過(guò)將驅(qū)動(dòng)程序添加到j(luò)ava.lang.System的屬性jdbc.drivers中。初始化DriverManager類時(shí),它自動(dòng)搜索系統(tǒng)屬性jdbc.drvers且加載其中包含的一個(gè)或多個(gè)驅(qū)動(dòng)程序。例如下面的代碼準(zhǔn)備加載三個(gè)驅(qū)動(dòng)程序類:
jdbc.drivers=ei.bar.Driver:bee.sql.Driver:see.test.ourDriver;3.建立連接與數(shù)據(jù)庫(kù)建立連接的方法包括:
DriverManager.getConnection(String
url)
DriverManager.getConnection(String
url,Propertiespro)
DriverManager.getConnection(String
url,String
user,Stringpassword)
其中,url指出使用哪個(gè)驅(qū)動(dòng)程序以及連接數(shù)據(jù)庫(kù)所需的其它信息。其格式為:
jdbc:<subprotocol>:<subname>例如:
Stringurl=“jdbc:microsoft:sqlserver://localhost:1433;User=JavaDB;Password=javadb;DatabaseName=northwind”;這里,subprotocol為microsoft,而subname為sqlserver及其后的內(nèi)容。至于用戶名和口令也是存取數(shù)據(jù)所需的信息。有時(shí)候,可以采用另一種方式建立連接:
Stringurl=“jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=northwind”;
Connectioncon=DriverManager.getConnection(url,”JavaDB”,”javadb”);4.執(zhí)行SQL語(yǔ)句與數(shù)據(jù)庫(kù)建立連接之后,需要向訪問(wèn)的數(shù)據(jù)庫(kù)發(fā)送SQL語(yǔ)句。在特定的程序環(huán)境和功能需求下,可能需要不同的SQL語(yǔ)句,例如數(shù)據(jù)庫(kù)的增刪改查等操作,或者數(shù)據(jù)庫(kù)或表的創(chuàng)建及維護(hù)操作等等。需要說(shuō)明的是:Java程序中所用到的SQL語(yǔ)句是否能得到正確的執(zhí)行,是否會(huì)產(chǎn)生異?;蝈e(cuò)誤,需要關(guān)注的不僅是語(yǔ)句本身的語(yǔ)法正確性,而且關(guān)注所訪問(wèn)的數(shù)據(jù)庫(kù)是否支持,例如有的數(shù)據(jù)庫(kù)不支持存儲(chǔ)過(guò)程操作,則發(fā)送調(diào)用存儲(chǔ)過(guò)程的語(yǔ)句即拋出異常。有三個(gè)類用于向數(shù)據(jù)庫(kù)發(fā)送SQL語(yǔ)句:
(1)Statement類,調(diào)用其createStatement()方法可以創(chuàng)建語(yǔ)句對(duì)象,然后利用該語(yǔ)句對(duì)象可以向數(shù)據(jù)庫(kù)發(fā)送具體的SQL語(yǔ)句。例如:
Stringquery=“select*fromtable1”;//查詢語(yǔ)句
Satement
st=con.createStatement();//或用帶參數(shù)的createStatement()方法
ResultSet
rs=st.executeQuery(query);//發(fā)送SQL語(yǔ)句,獲得結(jié)果
(2)PreparedStatement類,調(diào)用其方法prepareStatement()創(chuàng)建一編譯預(yù)處理語(yǔ)句對(duì)象,可以向數(shù)據(jù)庫(kù)發(fā)送帶有參數(shù)的SQL語(yǔ)句。該類有一組setXXX方法,用設(shè)置參數(shù)值。這些參數(shù)被傳送到數(shù)據(jù)庫(kù),預(yù)處理語(yǔ)句被執(zhí)行。這個(gè)過(guò)程類似于給函數(shù)傳遞參數(shù)之后執(zhí)行函數(shù),完成預(yù)期的處理。使用PreparedStatement與使用Statement相比較有較高的效率,關(guān)于這一點(diǎn)詳見(jiàn)后面相關(guān)部分的闡述。PreparedStatement
ps;
ResultSet
rs=null;Stringquery="selectname,age,addrfromxsdawhereaddr=?";
ps=con.prepareStatement(query);ps.setString(1,"hei");
rs=ps.executeQuery();
(3)CallableStatement類的方法prepareCall()可用于創(chuàng)建對(duì)象,該對(duì)象用于向數(shù)據(jù)庫(kù)發(fā)送一調(diào)用某存儲(chǔ)過(guò)程的SQL語(yǔ)句。prepareCall()和prepareStatement()一樣,所創(chuàng)建的語(yǔ)句允許帶有參數(shù),用setXXX()設(shè)置輸入?yún)?shù),即IN參數(shù),同時(shí)需接收和處理OUT參數(shù)、INOUT參數(shù)以及存儲(chǔ)過(guò)程的返回值,概要說(shuō)明其使用方法的語(yǔ)句例子如下:CallableStatement
cstmt;
ResultSet
rs;
cstmt=con.prepareCall("{?=callstat(?,?)}");//stat是一存儲(chǔ)過(guò)程的名字,它有兩個(gè)參數(shù),且有返回值
cstmt.setString(2,”JavaProgrammingLanguage”);
rs=cstmt.executeQuery();5.檢索結(jié)果數(shù)據(jù)庫(kù)執(zhí)行傳送到的SQL語(yǔ)句,結(jié)果有多種存儲(chǔ)位置,這與所執(zhí)行的語(yǔ)句有關(guān)。以查詢語(yǔ)句select為例,其結(jié)果需返回到程序中一結(jié)果集對(duì)象,即前面語(yǔ)句例子中的ResultSet之對(duì)象rs。rs可看作是一個(gè)表子集,有若干行和若干列,行列的具體數(shù)量與查詢條件及滿足查詢條件的記錄數(shù)有關(guān)。要瀏覽該表內(nèi)容可以借助ResultSet類的相關(guān)方法完成。例如行指針移動(dòng)方法rs.next()和取列內(nèi)容的方法rs.getXXX()等。若是執(zhí)行數(shù)據(jù)更新語(yǔ)句update,則返回的是成功進(jìn)行更新的數(shù)據(jù)庫(kù)記錄行數(shù),所以,檢索結(jié)果操作要依程序的具體內(nèi)容而定。
6.關(guān)閉連接完成對(duì)數(shù)據(jù)庫(kù)得操作之后應(yīng)關(guān)閉與常用數(shù)據(jù)庫(kù)的連接。關(guān)閉連接使用close()方法。格式如下:
con.close();2.1.4JDBC常用APIJDBCAPI提供的類和接口是在java.sql包中定義的。1.DriverManager類DriverManager類的常用方法:1)staticvoidderegisterDriver(Driverdriver)方法,從DriverManager的列表中刪除一個(gè)驅(qū)動(dòng)程序。2)static
Connection
getConnection(String
url)方法,建立到給定數(shù)據(jù)庫(kù)URL的連接。3)static
Connection
getConnection(String
url,Properties
info)方法,用給定的數(shù)據(jù)庫(kù)URL和相關(guān)信息(用戶名、用戶密碼等屬性)來(lái)創(chuàng)建一個(gè)連接。4)static
Connection
getConnection(String
url,String
user,String
password)方法,按給定的數(shù)據(jù)庫(kù)URL、用戶名和用戶密碼創(chuàng)建一個(gè)連接。5)static
Driver
getDriver(String
url)方法,查找給定URL下的驅(qū)動(dòng)程序。6)static
Enumeration<Driver> getDrivers()方法,獲得當(dāng)前調(diào)用方可以訪問(wèn)的所有已加載JDBC驅(qū)動(dòng)程序的Enumeration。7)static
int
getLoginTimeout()方法,獲得驅(qū)動(dòng)程序連接到某一數(shù)據(jù)庫(kù)時(shí)可以等待的最長(zhǎng)時(shí)間,以秒為單位。8)static
PrintWriter
getLogWriter()方法,檢索記錄寫(xiě)入器。9)static
voidprintln(String
message)方法,將一條消息打印到當(dāng)前JDBC記錄流中。10)static
voidregisterDriver(Driver
driver)方法,向DriverManager注冊(cè)給定驅(qū)動(dòng)程序。2.Connection類Connection類有如下常量:1)static
int
TRANSACTION_NONE指示不支持事務(wù)。2)static
int
TRANSACTION_READ_UNCOMMITTED說(shuō)明一個(gè)事務(wù)在提交前其變化對(duì)于其他事務(wù)而言是可見(jiàn)的。這樣可能發(fā)生臟讀(dirtyread)、不可重復(fù)讀(unrepeatedread)和虛讀(phantomread)。3)static
int
TRANSACTION_READ_COMMITTED說(shuō)明讀取未提交的數(shù)據(jù)是不允許的。防止發(fā)生臟讀的情況,但不可重復(fù)讀和虛讀仍有可能發(fā)生。4)static
int
TRANSACTION_REPEATABLE_READ說(shuō)明事務(wù)保證能夠再次讀取相同的數(shù)據(jù)而不會(huì)失敗,但虛讀有可能發(fā)生。5)static
int
TRANSACTION_SERIALIZABLE指示防止發(fā)生臟讀、不可重復(fù)讀和虛讀的常量。Connection類的常用方法:1)voidclearWarnings()方法,清除此Connction對(duì)象報(bào)告的所有警告。2)voidclose()方法,斷開(kāi)此Connction對(duì)象和數(shù)據(jù)庫(kù)的連接,而不是等待它們被自動(dòng)釋放。3)voidcommit()方法,使自從上一次提交/回滾以來(lái)進(jìn)行的所有更改成為持久更改,并釋放此Connction
對(duì)象當(dāng)前保存的所有數(shù)據(jù)庫(kù)鎖定。4)Statement
createStatement()方法,創(chuàng)建一個(gè)Statement對(duì)象,用來(lái)將SQL語(yǔ)句發(fā)送到數(shù)據(jù)庫(kù)。5)Statement
createStatement(int
resultSetType,int
resultSetConcurrency)方法,創(chuàng)建一個(gè)Statement對(duì)象,該對(duì)象將生成具有給定類型和并發(fā)性的ResultSet對(duì)象。6)Statement
createStatement(int
resultSetType,int
resultSetConcurrency,int
resultSetHoldability)方法,創(chuàng)建一個(gè)Statement對(duì)象,該對(duì)象將生成具有給定類型、并發(fā)性和可保存性的ResultSet對(duì)象。
3.Statement類
Statement類的常用方法包括:1)voidaddBatch(String
sql)方法,將給定的SQL命令添加到此Statement對(duì)象的當(dāng)前命令列表中。2)voidclearBatch()方法,清空此Statement對(duì)象的當(dāng)前SQL命令列表。3)voidclose()方法,立即釋放此Statement對(duì)象的數(shù)據(jù)庫(kù)和JDBC資源,而不是等待該對(duì)象自動(dòng)關(guān)閉時(shí)發(fā)生此操作。4)boolean
execute(String
sql)方法,執(zhí)行給定的SQL語(yǔ)句,該語(yǔ)句可能返回多個(gè)結(jié)果。5)int[]executeBatch()方法,將一批命令提交給數(shù)據(jù)庫(kù)來(lái)執(zhí)行,如果全部命令執(zhí)行成功,則返回更新計(jì)數(shù)組成的數(shù)組。6)ResultSet
executeQuery(String
sql)方法,執(zhí)行給定的SQL語(yǔ)句,該語(yǔ)句返回單個(gè)ResultSet對(duì)象。4.PreparedStatement類1)voidaddBatch()方法,將一組參數(shù)添加到此PreparedStatement對(duì)象的批處理命令中。2)boolean
execute()方法,在此PreparedStatement對(duì)象中執(zhí)行SQL語(yǔ)句,該語(yǔ)句可以是任何種類的SQL語(yǔ)句。3)ResultSet
executeQuery()方法,在此PreparedStatement對(duì)象中執(zhí)行SQL查詢,并返回該查詢生成的ResultSet對(duì)象。
4)int
executeUpdate()方法,在此PreparedStatement對(duì)象中執(zhí)行SQL語(yǔ)句,該語(yǔ)句必須是一個(gè)SQLINSERT、UPDATE或DELETE語(yǔ)句;或者是一個(gè)什么都不返回的SQL語(yǔ)句,比如DDL語(yǔ)句。5)ResultSetMetaData
getMetaData()方法,檢索包含有關(guān)ResultSet
對(duì)象的列消息的ResultSetMetaData
對(duì)象,ResultSet
對(duì)象將在執(zhí)行此PreparedStatement對(duì)象時(shí)返回。6)ParameterMetaData
getParameterMetaData()方法,檢索此PreparedStatement對(duì)象的參數(shù)的編號(hào)、類型和屬性。5.CallableStatement類
CallableStatement類的方法主要有三種,設(shè)置參數(shù)的系列set方法和獲取參數(shù)的系列g(shù)et方法以及注冊(cè)輸出參數(shù)方法。下面分別示例說(shuō)明之。1)boolean
getBoolean(int
parameterIndex)方法,以Java編程語(yǔ)言中boolean值的形式檢索指定的JDBCBIT參數(shù)的值。2)boolean
getBoolean(String
parameterName)方法,以Java編程語(yǔ)言中boolean值的形式檢索JDBCBIT參數(shù)的值。3)bytegetByte(int
parameterIndex)方法,以Java編程語(yǔ)言中byte的形式檢索指定的JDBCTINYINT參數(shù)的值。4)shortgetShort(int
parameterIndex)方法,以Java編程語(yǔ)言中short值的形式檢索指定的JDBCSMALLINT參數(shù)的值。5)String
getString(int
parameterIndex)方法,以Java編程語(yǔ)言中String的形式檢索指定的JDBCCHAR、VARCHAR或LONGVARCHAR參數(shù)的值。6)voidregisterOutParameter(int
parameterIndex,int
sqlType)方法,以parameterIndex為參數(shù)順序位置將OUT參數(shù)注冊(cè)為JDBC類型sqlType。必須在執(zhí)行存儲(chǔ)過(guò)程之前調(diào)用此方法。由sqlType指定的OUT參數(shù)的JDBC類型確定必須用于get方法來(lái)讀取該參數(shù)值的Java類型。這種registerOutParameter應(yīng)該在參數(shù)是JDBC類型NUMERIC或DECIMAL時(shí)使用。6.ResultSet類該類的幾個(gè)常量的作用如下:1)static
int
CLOSE_CURSORS_AT_COMMIT,該常量指示調(diào)用Cmit
方法時(shí)應(yīng)該關(guān)閉ResultSet對(duì)象。2)static
int
CONCUR_READ_ONLY,該常量指示不可以更新的ResultSet對(duì)象的并發(fā)模式。3)static
int
CONCUR_UPDATABLE,該常量指示可以更新的ResultSet對(duì)象的并發(fā)模式。4)static
int
FETCH_FORWARD,該常量指示將按正向(即從第一個(gè)到最后一個(gè))處理結(jié)果集中的行。5)static
int
FETCH_REVERSE,該常量指示將按反向(即從最后一個(gè)到第一個(gè))處理結(jié)果集中的行處理。6)static
int
FETCH_UNKNOWN,該常量指示結(jié)果集中的行的處理順序未知。7)static
int
HOLD_CURSORS_OVER_COMMIT,該常量指示調(diào)用Cmit
方法時(shí)不應(yīng)關(guān)閉對(duì)象。8)static
int
TYPE_FORWARD_ONLY,該常量指示指針只能向前移動(dòng)的ResultSet對(duì)象的類型。10)static
int
TYPE_SCROLL_INSENSITIVE,該常量指示可滾動(dòng)但通常不受其他的更改影響的ResultSet對(duì)象的類型。11)static
int
TYPE_SCROLL_SENSITIVE,該常量指示可滾動(dòng)并且通常受其他的更改影響的ResultSet對(duì)象的類型。ResultSet類的方法按其功能可以分為二類,即指針移動(dòng)方法和數(shù)據(jù)操作方法。這里僅舉例說(shuō)明這兩類方法的功能。1)boolean
absolute(int
row)方法,將指針移動(dòng)到此ResultSet對(duì)象的給定行編號(hào)。2)voidafterLast()方法,將指針移動(dòng)到此ResultSet對(duì)象的末尾,正好位于最后一行之后。3)voidbeforeFirst()方法,將指針移動(dòng)到此ResultSet對(duì)象的開(kāi)頭,正好位于第一行之前。4)boolean
first()方法,將指針移動(dòng)到此ResultSet對(duì)象的第一行。5)boolean
isAfterLast()方法,檢索指針是否位于此ResultSet對(duì)象的最后一行之后。6)boolean
isBeforeFirst()方法,檢索指針是否位于此ResultSet對(duì)象的第一行之前。7)boolean
isFirst()方法,檢索指針是否位于此ResultSet對(duì)象的第一行。8)boolean
isLast()方法,檢索指針是否位于此ResultSet對(duì)象的最后一行。9)boolean
last()方法,將指針移動(dòng)到此ResultSet對(duì)象的最后一行。10)voidmoveToCurrentRow()方法,將指針移動(dòng)到記住的指針位置,通常為當(dāng)前行。11)voidmoveToInsertRow()方法,將指針移動(dòng)到插入行。將指針置于插入行上時(shí),當(dāng)前的指針位置會(huì)被記住。插入行是一個(gè)與可更新結(jié)果集相關(guān)聯(lián)的特殊行。它實(shí)際上是一個(gè)緩沖區(qū),在將行插入到結(jié)果集前可以通過(guò)調(diào)用更新方法在其中構(gòu)造新行。當(dāng)指針位于插入行上時(shí),僅能調(diào)用更新方法、獲取方法以及insertRow方法。每次在調(diào)用insertRow之前調(diào)用此方法時(shí),必須為結(jié)果集中的所有列分配值。在對(duì)列值調(diào)用獲取方法之前,必須調(diào)用更新方法。12)boolean
next()方法,將指針從當(dāng)前位置下移一行。ResultSet指針最初位于第一行之前;第一次調(diào)用next方法使第一行成為當(dāng)前行;第二次調(diào)用使第二行成為當(dāng)前行,依此類推。如果開(kāi)啟了對(duì)當(dāng)前行的輸入流,則調(diào)用next方法將隱式關(guān)閉它。讀取新行時(shí),將清除ResultSet對(duì)象的警告鏈。7.Date類
java.sql.Date與java.util.Date配合使用可以方便地處理應(yīng)用程序中的日期型數(shù)據(jù)。下面的代碼段可以對(duì)此做簡(jiǎn)要說(shuō)明:
Dated1=newDate();//d1為當(dāng)前日期,某學(xué)生今日在圖書(shū)館借閱圖書(shū)
int
maxDays=60;//一本書(shū)的規(guī)定借閱天數(shù)60天
Dated2=newDate(d1.getTime()+60*24*60*60*1000);//d2為應(yīng)還書(shū)日期若要與數(shù)據(jù)庫(kù)交互,例如將該日期寫(xiě)入數(shù)據(jù)庫(kù)相應(yīng)字段,需借助java.sql.Date:
rs.moveToInsertRow();……java.sql.Dated3=newjava.sql.Date(d2.getTime);
rs.updateDate(“應(yīng)還日期”,d3);//將所借之書(shū)的應(yīng)還日期寫(xiě)入數(shù)據(jù)庫(kù)
……
rs.insertRow();8.元數(shù)據(jù)類Java定義的元數(shù)據(jù)(MetaData)有以下三種:DatabaseMetadata用于獲得關(guān)于數(shù)據(jù)庫(kù)和數(shù)據(jù)表的信息。ResultSetMetaData用于獲得關(guān)于結(jié)果集的信息。ParameterMetaData用于獲得預(yù)處理語(yǔ)句預(yù)處理語(yǔ)句對(duì)象參數(shù)的類型和屬性信息。2.1.5數(shù)據(jù)庫(kù)連接范例1.連接Oracle數(shù)據(jù)庫(kù)(用thin模式)
Class.forName(“oracle.jdbc.driver.OracleDriver”);Stringurl=“jdbc:oracle:thin:@localhost:1521:db”;Connectioncon=DriverManager.getConnection(url,user,password);Statementstmt=con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CUNCUR_UPDATABLE);2.連接MySQL數(shù)據(jù)庫(kù)
Class.forName(“com.mysql.jdbc.Driver”);Stringurl=“jdbc:mysql://localhost:3306/db”;Connectioncon=DriverManager.getConnection(url,user,password);Statementstmt=con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CUNCUR_UPDATABLE);3.連接SqlServer數(shù)據(jù)庫(kù)
Class.forName(“com.microsoft.jdbc.sqlserver.SQLServerDriver”);
Stringurl=“jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=db”;Stringuser=”sa”;Stringpassword=””;
Connectioncon=DriverManager.getConnection(url,user,password);Statementstmt=con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CUNCUR_UPDATABLE);2.2數(shù)據(jù)庫(kù)基本操作
2.2.1數(shù)據(jù)插入操作Insert語(yǔ)句格式如下:
INSERTINTO<表名>[(字段名[,字段名]…)]VALUES(常量[,常量]…)由于字段的類型不同,在values中的值的寫(xiě)法要求也不同。概括起來(lái)說(shuō)有如下幾點(diǎn):(1)數(shù)值型字段,可以直接寫(xiě)數(shù)值;(2)字符型字段,其值要加單引號(hào)。(3)日期型字段,其值要加單引號(hào),同時(shí)還要注意年、月、日的次序。例如,要向表member中插入一行數(shù)據(jù)的SQL語(yǔ)句是:INSERTINTOmember(name,age,sex,wage,addr)VALUES('LiMing',40,'男',4500,'北京市')INSERTINTOemp(empno,hiredate)VALUES(8888,to_date(‘2002-09-08’,’YYYY-MM-DD’))向表中插入NULL值需要滿足以下幾點(diǎn):(1)插入NULL的列在表中的定義不能為NOTNULL。(2)插入NULL的列在表的定義不能為主鍵或作為另外表的外鍵。(3)插入NULL的列在表的定義里不能有唯一的約束。對(duì)很多數(shù)據(jù)庫(kù)而言,對(duì)數(shù)據(jù)的插入、刪除和更新操作都有兩種可選的操作模式:直接使用SQL語(yǔ)句插入(或更新、刪除)模式和通過(guò)可更新的結(jié)果集對(duì)象間接插入(或更新、刪除)。且記,我們?cè)趧?chuàng)建語(yǔ)句對(duì)象時(shí)用下面的形式:
Statementstmt=con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CUNCUR_UPDATABLE);其中,參數(shù)ResultSet.CUNCUR_UPDATABLE的作用正是為了使該語(yǔ)句生成的結(jié)果對(duì)象是可更新結(jié)果集,它可被用來(lái)插入、更新、刪除記錄內(nèi)容。下面的程序段說(shuō)明了如何利用可更新結(jié)果集進(jìn)行數(shù)據(jù)插入:
rs.moveToInsertRow();
rs.updateString("name","'LiMing");rs.updateInt("age",40);
rs.updateString("sex","男");rs.updateInt("wage",50000);
rs.updateString("addr","北京市");
rs.insertRow();試比較若為交互操作引入變量在上面的操作中和在SQLINSERT語(yǔ)句中的情形,何者更方便是一目了然的??纯聪旅娴腟QLINSERT語(yǔ)句,體會(huì)一下惱人的拼串過(guò)程:
Stringsqlins="INSERTINTOstudentsvalues('"+sno+"','"+name+"','"+sex+"','"+birthday+"','"+"','"+department+"')";2.2.2數(shù)據(jù)刪除操作Delete語(yǔ)句的格式為:
DELETEFROM<表名>WHERE<條件表達(dá)式>例如:
DELETEFROMtable1WHERENo=7658從表table1中刪除一條記錄,其字段No的值為7658。使用可更新結(jié)果集的刪除操作,參見(jiàn)下面的代碼段:stmt=con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDADABLE);con.setAutoCommit(false);Stringsqlst=“select*frommember”;
rs=stmt.executeQuery(sqlst);rs.relative(4);//移動(dòng)到第4條記錄
rs.deleteRow();//從結(jié)果集和底層數(shù)據(jù)庫(kù)刪除該記錄
mit();2.2.3數(shù)據(jù)更新操作數(shù)據(jù)更新語(yǔ)句的命令格式為:
UPDATE<table_name>SETcolume_name=‘xxx’WHERE<條件表達(dá)式>例如語(yǔ)句:
UPDATEEMPSETJOB=’MANAGER’WHERENAME=’MATIN’對(duì)數(shù)據(jù)表EMP中姓名為MATIN的職工數(shù)據(jù)進(jìn)行了修改,將其工作名稱改為MANAGER。向數(shù)據(jù)庫(kù)發(fā)送數(shù)據(jù)更新的SQL語(yǔ)句是通過(guò)調(diào)用方法executeUpdate()完成的:Stringss="updatexsdasetage=age+1wherename='yang'";
stmt.executeUpdate(ss);下面的代碼說(shuō)明使用可更新結(jié)果集進(jìn)行更新操作的方法。
rs=stmt.executeQuery("select*frommemberwhereage=16");
rs.first();rs.updateInt("wage",3000);
rs.updateRow();
rs.next();rs.updateInt("wage",4000);
rs.updateRow();
rs.next();
rs.updateString("addr","上海市");
rs.updateRow();上面的代碼對(duì)連續(xù)3條記錄的wage字段和addr字段值進(jìn)行了更新操作。2.2.4數(shù)據(jù)查詢操作查詢語(yǔ)句的語(yǔ)句格式如下:
SELECT[DISTINCT]{column1,column2,…}FROMtablename
WHERE{conditions}GROUPBY{conditions}HAVING{conditions}
ORDERBY{conditions}[ASC/DESC];說(shuō)明:SELECT子句用于指定檢索數(shù)據(jù)庫(kù)中的哪些列,若要檢索所有列可以不必列出所有列名,只用*表示即可。FROM子句用于指定從哪一個(gè)表或者視圖中檢索數(shù)據(jù)。選項(xiàng)DISTINCT指明顯式結(jié)果不重復(fù),無(wú)此選項(xiàng)則顯示所有記錄可能重復(fù)。例如下面的語(yǔ)句只顯示姓名不同的記錄:
selectdistinctNamefromperson;WHERE子句用于指定查詢條件,若condition條件表達(dá)式的值為T(mén)RUE,則檢索相應(yīng)的行,若條件表達(dá)式的值為FALSE,則不會(huì)檢索該行數(shù)據(jù)。GROUPBY指出記錄分組的條件,例如進(jìn)行分組統(tǒng)計(jì)。HAVING則是用于限制分組統(tǒng)計(jì)的結(jié)果。例如統(tǒng)計(jì)emp表中不同部門(mén)(depno)不同崗位(job)的平均工資(AVG(sal))大于3000的所有記錄的語(yǔ)句如下:
SELECTdepno,job,AVG(sal)FROMempGROUPBYdepno,jobHAVINGAVG(sal)>3000;注意:HAVING子句必須跟在GROUPBY子句的后面。ORDERBY子句指出查詢結(jié)果排序顯示,可為升序(ASC)或可為降序(DESC)排列。2.2.5事務(wù)處理所謂事務(wù),概指一系列的數(shù)據(jù)庫(kù)操作,這些操作要么全做,要么全不做,是一個(gè)不可分割的工作單元,也可以說(shuō)是數(shù)據(jù)庫(kù)應(yīng)用程序中的一個(gè)基本邏輯單元。它可能是一條SQL語(yǔ)句、一組SQL語(yǔ)句或者一個(gè)完整的程序。這體現(xiàn)的是事務(wù)的原子性需求,對(duì)事務(wù)還有其他的需求如一致性、隔離性、持久性。JDBC事務(wù)處理可采用隔離級(jí)別控制數(shù)據(jù)讀取操作。JDBC支持5個(gè)隔離級(jí)別設(shè)置,其名字和含義如下所示:staticintTRANSACTION_NONE不支持事務(wù)staticintTRANSACTION_READ_COMMITED臟讀、不可重復(fù)讀、錯(cuò)誤讀取可能出現(xiàn)staticintTRANSACTION_READ_UNCOMMITED禁止臟讀,不可重復(fù)讀、錯(cuò)誤讀取可能出現(xiàn)staticintTRANSACTION_REPEATABLE_READ禁止臟讀、不可重復(fù)讀,錯(cuò)誤讀取可能出現(xiàn)staticintTRANSACTION_SERIALIZABLE禁止臟讀、不可重復(fù)讀、錯(cuò)誤讀取。上面的5個(gè)常量是Connection中提供的。同樣Connection提供了方法進(jìn)行隔離級(jí)別設(shè)置:
setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ)一個(gè)事務(wù)也許包含幾個(gè)任務(wù),正象超市里面完成一個(gè)事務(wù)也要包括幾個(gè)任務(wù)一樣。超市里的一個(gè)事務(wù)對(duì)應(yīng)于一次消費(fèi)活動(dòng)的全過(guò)程。它是由若干個(gè)任務(wù)構(gòu)成的。確定購(gòu)買項(xiàng)目,登記每個(gè)項(xiàng)目,然后計(jì)算總額,之后支付。只有當(dāng)每個(gè)任務(wù)結(jié)束后,事務(wù)才結(jié)束。如果其中的一個(gè)任務(wù)失敗,則事務(wù)失敗,前面完成的任務(wù)也要恢復(fù)。這是基本性質(zhì)。Connection中下面三個(gè)方法完成基本的事務(wù)管理:1)setAutoCommit(booleantrue/false)方法,設(shè)置自動(dòng)提交屬性AutoCommit,默認(rèn)為true。2)rollback()方法,回滾事務(wù)。3)commit()方法,事務(wù)提交。在調(diào)用了commit()方法之后,所有為這個(gè)事務(wù)創(chuàng)建的結(jié)果集對(duì)象都被關(guān)閉了,除非通過(guò)createStatement()方法傳遞了參數(shù):HOLD_CURSORS_OVER_COMMIT其功能相對(duì)的另一個(gè)參數(shù)為:CLOSE_CURSORS_AT_COMMIT在commit()方法被調(diào)用時(shí)關(guān)閉ResultSet對(duì)象。事務(wù)中若包含多個(gè)任務(wù),當(dāng)事務(wù)失敗時(shí),也許其中部分任務(wù)不需要被回滾,例如處理一個(gè)訂單要完成3個(gè)任務(wù):更新消費(fèi)者帳戶表,定單插入到待處理的定單表,給消費(fèi)者發(fā)一確認(rèn)電子郵件。如果上述3個(gè)任務(wù)中完成了前2個(gè)只是最后一個(gè)因?yàn)猷]件服務(wù)器掉線而未完成,那么不需要對(duì)整個(gè)事務(wù)回滾。如何處理有數(shù)量選擇與控制的回滾操作?我們需要引進(jìn)保存點(diǎn)(savepoint)來(lái)控制回滾的數(shù)量。Jdbc3.0支持保存點(diǎn)的操作。所謂保存點(diǎn),就是對(duì)事務(wù)的某些子任務(wù)設(shè)置符號(hào)標(biāo)識(shí),用以為回滾操作提供位置指示。關(guān)于保存點(diǎn)的方法主要有以下三個(gè):(1)setSavepoint(“保存點(diǎn)名稱”)方法,在某子任務(wù)前設(shè)置一保存點(diǎn)。(2)releaseSavepoint(“保存點(diǎn)名稱”)方法,釋放一指定名稱的保存點(diǎn)。(3)rollback(“保存點(diǎn)名稱”)方法,指示事務(wù)回滾到指定的保存點(diǎn)。2.3數(shù)據(jù)庫(kù)存取優(yōu)化
2.3.1常用技術(shù)(1)優(yōu)化SQL語(yǔ)句的執(zhí)行效率(2)定義和調(diào)用存儲(chǔ)過(guò)程(3)采用編譯預(yù)處理(4)采用數(shù)據(jù)庫(kù)連接池技術(shù)(5)選擇合適的JDBC驅(qū)動(dòng)程序(6)優(yōu)化建立的連接2.3.2編譯預(yù)處理首先了解一下PreparedStatement這個(gè)類。PreparedStatement是Statement的一個(gè)子類。PreparedStatement類與Statement類的一個(gè)重要區(qū)別是:用Statement定義的語(yǔ)句是一個(gè)功能明確而具體的語(yǔ)句,而用PreparedStatement類定義的SQL語(yǔ)句中則包含有一個(gè)或多個(gè)問(wèn)號(hào)(“?”)占位符,它們對(duì)應(yīng)于多個(gè)IN參數(shù)。帶著占位符的SQL語(yǔ)句被編譯,而在后續(xù)執(zhí)行過(guò)程中,這些占位符需要用setXXX方法設(shè)置為具體的IN參數(shù)值,這些語(yǔ)句發(fā)送至數(shù)據(jù)庫(kù)獲得執(zhí)行。下面給出若干編譯預(yù)處理語(yǔ)句例子說(shuō)明PreparedStatement的用法:首先創(chuàng)建對(duì)象:PreparedStatement
pstmt=con.prepareStatement(“updatetable1setx=?wherey=?”);在對(duì)象pstmt中包含了語(yǔ)句“updatetable1setx=?wherey=?”,該語(yǔ)句被發(fā)送到DBMS進(jìn)行編譯預(yù)處理,為執(zhí)行做準(zhǔn)備。然后為每個(gè)IN參數(shù)設(shè)定參數(shù)值,即每個(gè)占位符?(Placeholder)對(duì)應(yīng)一個(gè)參數(shù)值。設(shè)定參數(shù)值是通過(guò)調(diào)用setXXX方法實(shí)現(xiàn)的,其中XXX是與參數(shù)相對(duì)應(yīng)的類型,加入上面例子中參數(shù)類型為long,則用下面的代碼為參數(shù)設(shè)定值:pstmt.setLong(1,123456789);pstmt.setLong(2,987654321);這里的1和2是與占位符從左到右的次序相對(duì)應(yīng)的序號(hào)。注意它們不是從0開(kāi)始計(jì)數(shù)的。最后執(zhí)行語(yǔ)句
Pstmt.executeUpdate();程序例2.1用于說(shuō)明編譯預(yù)處理語(yǔ)句的使用方法。2.3.3調(diào)用存儲(chǔ)過(guò)程很多數(shù)據(jù)庫(kù)支持存儲(chǔ)過(guò)程功能。可以在數(shù)據(jù)庫(kù)中定義存儲(chǔ)過(guò)程,在Java中則可以調(diào)用存儲(chǔ)過(guò)程完成某些處理。這也是提高數(shù)據(jù)存取效率的方法。和編譯預(yù)處理操作提高效率的機(jī)制類似,采用存儲(chǔ)過(guò)程也是基于避免頻繁地與數(shù)據(jù)庫(kù)交互和更多地重用代碼以期減少時(shí)間開(kāi)銷從而提高效率的。關(guān)于存儲(chǔ)過(guò)程的定義的語(yǔ)法,可參閱介紹數(shù)據(jù)庫(kù)的書(shū)籍資料加以掌握。這里僅對(duì)Java中調(diào)用存儲(chǔ)過(guò)程的語(yǔ)法和應(yīng)用進(jìn)行討論。假設(shè)現(xiàn)已在SQLServer中建立如下兩個(gè)存儲(chǔ)過(guò)程,一個(gè)是無(wú)參的,一個(gè)是帶參數(shù)的。無(wú)參數(shù)存儲(chǔ)過(guò)程getCourseName用于按課程號(hào)查詢課程名。createproceduregetCourseNameasselectdistinctcourseNamefromgrade,coursewheregrade.courseID=course.courseID有參數(shù)存儲(chǔ)過(guò)程stat用于統(tǒng)計(jì)指定課程的平均分?jǐn)?shù)和學(xué)生數(shù),學(xué)生數(shù)用函數(shù)返回值返回給調(diào)用者,平均分?jǐn)?shù)則是通過(guò)輸出參數(shù)傳遞給調(diào)用者。@avgGradefloatoutput說(shuō)明參數(shù)@avgGrade類型為float,output指其為輸出參數(shù),即從存儲(chǔ)過(guò)程返回時(shí)向調(diào)用程序(Java程序)傳值,其作用
溫馨提示
- 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ù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 學(xué)校改造方案
- 智能配電終端項(xiàng)目風(fēng)險(xiǎn)分析和評(píng)估報(bào)告
- 中國(guó)農(nóng)林牧漁行業(yè)市場(chǎng)調(diào)查研究及投資前景預(yù)測(cè)報(bào)告
- 安全生產(chǎn)教育培訓(xùn)的總結(jié)
- 工業(yè)廢氣集中處理設(shè)施項(xiàng)目申請(qǐng)報(bào)告范本參考(立項(xiàng)申請(qǐng))
- 中國(guó)理化檢測(cè)行業(yè)投資分析及發(fā)展戰(zhàn)略研究咨詢報(bào)告
- 中國(guó)真空爐加熱室總成行業(yè)發(fā)展前景及投資戰(zhàn)略咨詢報(bào)告
- 【可行性報(bào)告】2025年探照燈行業(yè)項(xiàng)目可行性分析報(bào)告
- 安全管理目標(biāo)及責(zé)任書(shū)
- 2025年中國(guó)耦合桿式半獨(dú)立懸架行業(yè)發(fā)展監(jiān)測(cè)及發(fā)展趨勢(shì)預(yù)測(cè)報(bào)告
- 靜電放電(ESD)及其防護(hù)措施培訓(xùn)課件
- 離婚不離家協(xié)議書(shū)
- 社區(qū)干事考試試題及答案
- 2025年建筑工程管理考試試題及答案
- 2025年廣西南寧賓陽(yáng)縣昆侖投資集團(tuán)有限公司招聘筆試參考題庫(kù)含答案解析
- 2025年軍人離婚協(xié)議書(shū)范本
- DB11∕T045-2025醫(yī)學(xué)實(shí)驗(yàn)室質(zhì)量與技術(shù)要求
- 工程造價(jià)復(fù)審報(bào)告書(shū)范文
- 《星形膠質(zhì)細(xì)胞》課件
- SAP S4HANA 用戶操作手冊(cè)-成本控制CO操作手冊(cè)-002-訂單成本核算
- 幼兒園2025-2026學(xué)年度第一學(xué)期園本培訓(xùn)計(jì)劃
評(píng)論
0/150
提交評(píng)論