《Oracle數(shù)據(jù)庫應(yīng)用教程》課件第11章_第1頁
《Oracle數(shù)據(jù)庫應(yīng)用教程》課件第11章_第2頁
《Oracle數(shù)據(jù)庫應(yīng)用教程》課件第11章_第3頁
《Oracle數(shù)據(jù)庫應(yīng)用教程》課件第11章_第4頁
《Oracle數(shù)據(jù)庫應(yīng)用教程》課件第11章_第5頁
已閱讀5頁,還剩47頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

第11章

利用JDBC進行Oracle訪問

11.1概述

11.2OracleJDBC驅(qū)動程序

11.3OracleJDBC的使用

11.4實例

11.5小結(jié)

習(xí)題十一

上機實驗十一

11.1概

對ODBCAPI面向?qū)ο蟮姆庋b和重新設(shè)計使JDBC(JavaDataBaceConnectivity)易于學(xué)習(xí)和使用,而且利用JDBC能夠編寫不依賴于廠商的代碼,用以查詢和操縱數(shù)據(jù)庫。與所有JavaAPI一樣,它是面向?qū)ο蟮?,但并不是很高級別的對象集。JDBC可以訪問包括Oracle在內(nèi)的各種不同數(shù)據(jù)庫,但Oracle數(shù)據(jù)庫包含許多獨特的性質(zhì),只能通過使用標準JDBC的Oracle擴展來使用。Oracle擴展可盡可能地發(fā)揮JDBC的能力。

11.2OracleJDBC驅(qū)動程序

OracleJDBC驅(qū)動程序使Java程序中的JDBC語句可以訪問Oracle數(shù)據(jù)庫。OracleJDBC驅(qū)動程序有以下四種。

1.Thin驅(qū)動程序

Thin驅(qū)動程序?qū)Y源消耗最小,完全由Java編寫。它可以在獨立的Java應(yīng)用程序(包括JavaApplet)中使用,并且可以訪問所有版本的Oracle數(shù)據(jù)庫。

2.OCI驅(qū)動程序

OCI驅(qū)動程序比Thin驅(qū)動程序占用資源多,但性能好一點。它適合于部署在中間層的軟件,如Web服務(wù)器。OCI驅(qū)動程序是第二類驅(qū)動程序,不完全是用Java編寫的,還包含用C寫的代碼。

3.服務(wù)器端內(nèi)部驅(qū)動程序

服務(wù)器端內(nèi)部驅(qū)動程序提供對數(shù)據(jù)庫的直接訪問,OracleJVM使用它與數(shù)據(jù)庫進行通信。OracleJVM是與數(shù)據(jù)庫集成的虛擬機,可以使用OracleJVM將Java類裝載進數(shù)據(jù)庫,然后公布和運行這個類中包含的方法。

4.服務(wù)器端Thin驅(qū)動程序

服務(wù)器端Thin驅(qū)動程序也是由OracleJVM使用的,它提供對遠程數(shù)據(jù)庫的訪問。與Thin驅(qū)動程序一樣,這種驅(qū)動程序也完全使用Java編寫。

11.3OracleJDBC的使用

11.3.1導(dǎo)入JDBC包

要能使用JDBC,必須將所需的JDBC包導(dǎo)入Java程序。

importjava.sql.*;11.3.2注冊JDBC驅(qū)動程序

有兩種注冊O(shè)racleJDBC驅(qū)動程序的方法。第一種使用Class.forName("oracle.jdbc.

OracleDriver");第二種方法使用DriverManager。DriverManager類是

JDBC的管理層,作用于用戶和驅(qū)動程序之間。它跟蹤可用的驅(qū)動程序,并在數(shù)據(jù)庫和相應(yīng)驅(qū)動程序之間建立連接。另外,DriverManager類也處理諸如驅(qū)動程序登錄時間限制及登錄和跟蹤消息的顯示等事務(wù)。

DriverManager.registerDriver(neworacle.jdbc.OracleDriver());如果使用OracleJDBC驅(qū)動程序,則需要導(dǎo)入oracle.jdbc.driver.OracleDriver類,然后注冊這個類的實例。

Importoracle.jdbc.driver.OracleDriver;

DriverManager.registerDriver(neworacle.jdbc.driver.OracleDriver());

11.3.3打開數(shù)據(jù)流

加載

Driver類并在

DriverManager類中注冊后,即可與數(shù)據(jù)庫建立連接。

與數(shù)據(jù)庫建立連接的標準方法是調(diào)用DriverManager.getConnection。該方法接受含有某個

URL的字符串。DriverManager類(即所謂的

JDBC管理層)將嘗試找到可與那個

URL所代表的數(shù)據(jù)庫進行連接的驅(qū)動程序。DriverManager類存有已注冊的

Driver類的清單。當調(diào)用方法

getConnection時,它將檢查清單中的每個驅(qū)動程序,直到找到可與URL中指定的數(shù)據(jù)庫進行連接的驅(qū)動程序為止。Driver的方法connect使用這個

URL來建立實際的連接。

DriverManager.getConnection(URL,username,password);

JDBCURL提供了一種標識數(shù)據(jù)庫的方法,可以使相應(yīng)的驅(qū)動程序識別該數(shù)據(jù)庫并與之建立連接。實際上,驅(qū)動程序編程員決定用什么JDBCURL來標識特定的驅(qū)動程序。用戶不必關(guān)心如何形成JDBCURL,他們只需使用與所用驅(qū)動程序一起提供的URL即可。JDBC的作用是提供某些約定,驅(qū)動程序編程員在構(gòu)造JDBCURL時應(yīng)該遵循這些約定。JDBCURL的標準語法如下所示,它由三部分組成,各部分間用冒號分隔。

Jdbc:<子協(xié)議>:<子名稱>

JDBCURL的三個部分可分解如下:

jdbc為協(xié)議,JDBCURL中的協(xié)議總是jdbc;子協(xié)議為即將使用的驅(qū)動程序;子名稱是Oracle數(shù)據(jù)庫服務(wù)名。

username表示程序連接數(shù)據(jù)庫時使用的數(shù)據(jù)庫用戶名。

password表示用戶名口令。

以下例子使用getConnection()方法連接數(shù)據(jù)庫。

Connectioncon=DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:ORCL","scott","tiger");

這個例子使用的是OracleJDBCThin驅(qū)動程序。

11.3.4執(zhí)行SQL語句

Statement對象用于將

SQL語句發(fā)送給數(shù)據(jù)庫。Statement對象有三種:Statement、PreparedStatement(從

Statement繼承而來)和

CallableStatement(從

PreparedStatement繼承而來),它們是給定連接上執(zhí)行SQL語句的包容器,它們都專用于發(fā)送特定類型的SQL

語句。

Statement對象用于執(zhí)行不帶參數(shù)的簡單

SQL語句;PreparedStatement對象用于執(zhí)行帶或不帶

IN參數(shù)的預(yù)編譯

SQL語句;CallableStatement對象用于執(zhí)行對數(shù)據(jù)庫已存儲過程的調(diào)用。

1.創(chuàng)建

Statement對象

建立了到特定數(shù)據(jù)庫的連接之后,就可用該連接發(fā)送

SQL語句。Statement對象用

Connection的方法

createStatement創(chuàng)建,如下列代碼段所示:

Statementstmt=con.createStatement();

為了執(zhí)行

Statement對象,被發(fā)送到數(shù)據(jù)庫的

SQL語句將被作為參數(shù)提供給

Statement。

2.使用

Statement對象執(zhí)行語句

Statement接口提供了三種執(zhí)行

SQL語句的方法:executeQuery、executeUpdate和

execute。使用哪一種方法由

SQL語句所產(chǎn)生的內(nèi)容決定。方法

executeQuery用于產(chǎn)生單個結(jié)果集的語句,例如:

ResultSetrs=stmt.executeQuery("SELECTa,b,cFROMTable2");方法executeUpdate用于執(zhí)行INSERT、UPDATE或DELETE語句以及SQLDDL(數(shù)據(jù)定義語言)語句,例如CREATETABLE和DROPTABLE。INSERT、UPDATE或DELETE語句的效果是修改表中零行或多行中的一列或多列。executeUpdate的返回值是一個整數(shù),指示受影響的行數(shù)(即更新計數(shù))。對于CREATETABLE或DROPTABLE等不操作行的語句,executeUpdate的返回值總為零。

intline=stmt.executeUpdate("insertintouserinfovalues('juliet','juliet')");

如果預(yù)先不知道要執(zhí)行的SQL語句類型,則可使用方法execute,用于執(zhí)行返回多個結(jié)果集、多個更新計數(shù)或二者組合的語句。

3.關(guān)閉

Statement對象

Statement對象由

Java垃圾收集程序自動關(guān)閉。作為一種好的編程風(fēng)格,應(yīng)在不需要

Statement對象時顯式地關(guān)閉它們。這將立即釋放

DBMS資源,有助于避免潛在的內(nèi)存問題。語句如下:

stmt.close();11.3.5獲得查詢結(jié)果集

ResultSet包含符合

SQL語句中條件的所有行,并且通過一套

get方法(這些

get方法可以訪問當前行中的不同列)提供了對這些行中數(shù)據(jù)的訪問。ResultSet.next方法用于移動到

ResultSet中的下一行,使下一行成為當前行。結(jié)果集一般是一個表,其中有查詢所返回的列標題及相應(yīng)的值。

ResultSet維護指向其當前數(shù)據(jù)行的光標。每調(diào)用一次

next方法,光標向下移動一行。最初它位于第一行之前,因此第一次調(diào)用next時應(yīng)把光標置于第一行上,使它成為當前行。隨著每次調(diào)用next將導(dǎo)致光標向下移動一行,可按照從上至下的次序獲取ResultSet行。在

ResultSet對象或其父輩

Statement對象關(guān)閉之前,光標一直保持有效。使用方法如下:

ResultSetrs=stmt.executeQuery("select語句");

while(xt())

{

數(shù)據(jù)類型

variable_name=rs.get××(字段腳標或字段名);

}11.3.6關(guān)閉數(shù)據(jù)流

關(guān)閉數(shù)據(jù)流連接可采用Connection對象的close方法。即時關(guān)閉數(shù)據(jù)流可以減少內(nèi)存占用,關(guān)閉數(shù)據(jù)流的語句如下:

con.close();

11.3.7在JDBC中調(diào)用存儲過程

CallableStatement對象為所有的

DBMS提供了一種以標準形式調(diào)用存儲過程的方法。有兩種調(diào)用形式:一種帶結(jié)果參數(shù),另一種不帶結(jié)果參數(shù)。

在JDBC中,調(diào)用存儲過程的語法如下所示。注意,方括號表示其間的內(nèi)容是可選項,方括號本身并非語法的組成部分。

{call過程名[(?,?,...)]}

返回結(jié)果參數(shù)的存儲過程的語法如下:

{?=call過程名[(?,?,...)]}

不帶參數(shù)的存儲過程的語法如下:

{call過程名}

1.創(chuàng)建

CallableStatement對象

CallableStatement對象是用Connection方法prepareCall創(chuàng)建的。下面為創(chuàng)建

CallableStatement的實例,其中含有對存儲過程getEMPData調(diào)用。該過程有兩個變量,但不含結(jié)果參數(shù)。

CallableStatementcstmt=con.prepareCall("{callgetEMPData(?,?)}");

其中,?占位符為IN、OUT還是INOUT參數(shù)取決于存儲過程getEMPData。

2.IN和OUT參數(shù)

將IN參數(shù)傳給CallableStatement對象是通過setXXX方法來完成的。所傳入?yún)?shù)的類型決定了所用的setXXX方法(例如,用setFloat來傳入float值等)。

如果存儲過程返回OUT參數(shù),則在執(zhí)行CallableStatement對象以前先注冊每個OUT參數(shù)的JDBC類型,使用registerOutParameter方法來注冊。語句執(zhí)行完后,CallableStatement的getXXX方法將取回參數(shù)值。registerOutParameter使用的是JDBC類型(因此它與數(shù)據(jù)庫返回的JDBC類型匹配),而getXXX將之轉(zhuǎn)換為Java類型。

下面的例子先注冊O(shè)UT參數(shù),執(zhí)行由cstmt所調(diào)用的存儲過程,然后檢索在OUT參數(shù)中返回的值。方法setDouble給第一個IN參數(shù)傳入值,方法

getInt從第二個

OUT參數(shù)中取出一個整數(shù)。

CallableStatementcstmt=con.prepareCall("{callgetEMPData(?,?)}");

cstmt.setDouble(1,5000.0);

cstmt.registerOutParameter(2,java.sql.Types.INTEGER);

cstmt.execute();

intx=cstmt.getInt(2);

3.INOUT參數(shù)

既支持輸入又接受輸出的參數(shù)(INOUT參數(shù))不僅要調(diào)用registerOutParameter方法,還要調(diào)用合適的setXXX方法。setXXX方法將參數(shù)設(shè)置為輸入?yún)?shù),registerOutParameter方法將它的JDBC類型注冊為輸出參數(shù)。應(yīng)該引起注意的是,IN值的JDBC類型和提供給registerOutParameter方法的JDBC類型必須相同。

檢索輸出值時,應(yīng)使用對應(yīng)的getXXX方法。例如,Java類型為int的參數(shù)應(yīng)該使用方法

setInt來賦輸入值;應(yīng)該給registerOutParameter提供類型為INTEGER的

JDBC類型。

下例演示了一個存儲過程compute,其唯一參數(shù)是INOUT。方法setInt把此參數(shù)設(shè)為25,驅(qū)動程序?qū)⑺鳛镴DBCINTERGER類型送到數(shù)據(jù)庫中。然后,registerOutParameter將該參數(shù)注冊為JDBCINTEGER。執(zhí)行完該存儲過程后,將返回一個新的JDBCTINYINT值。方法getInt將把這個新值作為JavaInt類型檢索。

CallableStatementcstmt=con.prepareCall("{callcompute(?)}");

cstmt.setInt(1,25);

cstmt.registerOutParameter(1,java.sql.Types.INTEGER);

cstmt.executeUpdate();

intx=cstmt.getInt(1);

11.3.8處理SQL異常

當數(shù)據(jù)庫或JDBC驅(qū)動程序發(fā)生錯誤時,將拋出一個java.sql.SQLException。java.sql.SQLException類是java.sql.Exception類的子類。因此,所有的JDBC語句最好放在一個try/catch語句塊中,否則代碼就要拋出java.sql.SQLException。如果出現(xiàn)這種情況,則JVM還要試圖尋找合適的處理器來處理這個異常。如果沒有找到合適的,則使用默認的異常處理器來處理該異常。使用catch子句后,每當出現(xiàn)異常時,JVM會將控制轉(zhuǎn)移到運行這個catch子句的代碼。在此代碼中,可以顯示錯誤編碼和錯誤消息,這有助于判斷錯誤原因。

java.sql.SQLException類定義了四個方法,可以幫助查找并判斷出錯原因。

(1)getErrorCode():對于數(shù)據(jù)庫和JDBC驅(qū)動程序中發(fā)生的錯誤,此方法返回oracle的錯誤編碼(一個5位的數(shù)字)。

(2)getMessage():對于數(shù)據(jù)庫中發(fā)生的錯誤,此方法返回錯誤消息以及5位的錯誤編碼;對于JDBC驅(qū)動程序錯誤,此方法只返回錯誤消息。

(3)?getSQLState():

對于數(shù)據(jù)庫中發(fā)生的錯誤,此方法返回5位錯誤編碼和SQL的狀態(tài);對于JDBC驅(qū)動程序錯誤,此方法不返回任何有意義的內(nèi)容。

(4)printStackTrace():此方法顯示發(fā)生異常時的堆棧內(nèi)容。下面的例子將演示以上方法的使用。

try{}

catch(SQLExceptione)

{

e.printStackTrace();

System.out.println(e.getMessage());

System.out.println(e.getErrorCode());

System.out.println(e.getSQLState());

}

11.4實

1.實例一

在scott用戶模式下,添加一條記錄到EMP表,然后顯示10號部門的所有員工姓名。

提示:在eclipse編程環(huán)境下,需導(dǎo)入classes111.jar。

importjava.sql.*;

publicclassSimpleSQLExample{

publicstaticvoidmain(Stringargs[])

{

try{

//DriverManager.registerDriver(neworacle.jdbc.driver.OracleDriver());Class.forName(“oracle.jdbc.OracleDriver”);//兩種方式都可以

Connectioncon=DriverManager.getConnection("jdbc:oracle:thin:@localhost:

1521:ora9","scott","tiger");

Statementstmt=con.createStatement();

stmt.execute("insertintoemp(empno,ename,deptno,sal)values(8002,'atlas',10,5000)");

ResultSetrs=stmt.executeQuery("selectenamefromempwheredeptno=10");

while(rs.next())

{

Stringename=rs.getString(1);

System.out.println(ename);

}

stmt.close();

con.close();

}

catch(Exceptione)

{

System.out.print(e.toString());

}

}

}圖11-1簡單SQL語句程序

CLARK

KING

MILLER

atlas

2.實例2

創(chuàng)建一個給特定員工增加10%薪水的存儲過程,并返回最新的薪水值。使用JDBC調(diào)用該存儲過程,打印返回值。

存儲過程代碼如下:

createorreplaceprocedureraisesal(emp_nonumber,sal_varoutnumber)

as

begin

updateempsetsal=sal*1.1whereempno=emp_no;

selectsalintosal_varfromempwhereempno=emp_no;

end;

/給實例1中的8002號薪水為5000的員工漲工資,程序代碼如下:

importjava.sql.*;

publicclasscallprocExample{

publicstaticvoidmain(Stringargs[])

{

try{

//DriverManager.registerDriver(neworacle.jdbc.driver.OracleDriver());

Class.forName("oracle.jdbc.OracleDriver");

Connectioncon=DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:

ORa9","scott","tiger");

CallableStatementcstmt=con.prepareCall("{callraisesal(?,?)}");

cstmt.setInt(1,8002);

cstmt.registerOutParameter(2,Types.FLOAT);

cstmt.execute();

floatsal_var=cstmt.getFloat(2);

System.out.print(sal_var);

cstmt.close();

con.close();

}

catch(Exceptione)

{

System.out.print(e.toString());

}

}

}圖11-2調(diào)用存儲過程的程序

11.5小

結(jié)

JDBC是一個軟件層,允許開發(fā)者在Java中編寫客戶端/服務(wù)器程序,它提供了簡單的接口,用于執(zhí)行原始的SQL語句。Oracle支持簡單的JDBC訪問和開發(fā),提供了很多圖形化的應(yīng)用程序來支持和開發(fā)Java程序,如ContainerforJ2EE和Jdeveloper,它涵蓋了性能調(diào)整、開發(fā)J2EE組件和Java存儲過程等技術(shù)。

習(xí)題十一

一、選擇題

1.JDBC的組件是()、()和()。

2.使用()類調(diào)用存儲過程。

3.executeQuery的返回類型是()。

A.Result B.ResultSet

C.ResultsetD.以上選項都不正確

4.create命令是用()命令執(zhí)行的。

A.executeQueryB.execute

C.?executeUpdate D.?executeCreate二、編程題

1.編寫一個程序,用于創(chuàng)建一個具有以下列的student表:

stu_idnumber(5)

stu_namevarchar2(20)

agenumber(3)

2.編寫一個程序,往student表里插入三條數(shù)據(jù)。

3.編寫程序,檢索student表中的數(shù)據(jù),并按行打印所有的記錄信息。

上機實驗十一

實驗1創(chuàng)建一段Web程序,用Oracle數(shù)據(jù)源來檢索并顯示student表中的同學(xué)信息

目的和要求:

1.掌握JDBC類。

2.掌握連接訪問關(guān)閉數(shù)據(jù)流。

3.掌握傳送簡單的查詢語句。

實驗內(nèi)容:

importjava.sql.*;

publicclassLab1{

publicstaticvoidmain(Stringargs[])

{

try{

//DriverManager.registerDriver(neworacle.jdbc.driver.OracleDriver());

Class.forName("oracle.jdbc.OracleDriver");//兩種方式都可以

Connectioncon=DriverManager.getConnection

("jdbc:oracle:thin:@localhost:1521:ora9","scott","tiger");

Statementstmt=con.createStatement();

ResultSetrs=stmt.executeQuery("select*fromstudent");

while(rs.next())

{

System.out.println(rs.getInt(1)

+rs.getString(2)+rs.getInt(3));

}

stmt.close();

con.close();

}

catch(Exceptione)

{

System.out.print(e.toString());

}

}

}實驗2創(chuàng)建一段Web程序,在EMP中添加一個新雇員,要求用SQL語句傳遞參數(shù)

目的和要求:

1.掌握JDBC類。

2.掌握連接訪問關(guān)閉數(shù)據(jù)流。

3.掌握傳送預(yù)定義語句。

實驗內(nèi)容:

importjava.sql.*;

publicclassLab2{

publicstaticvoidmain(Stringargs[])

{

try{

//DriverManager.registerDriver(neworacle.jdbc.driver.OracleDriver());

Class.forName("oracle.jdbc.OracleDriver");//兩種方式都可以

溫馨提示

  • 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)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論