a亚洲精品_精品国产91乱码一区二区三区_亚洲精品在线免费观看视频_欧美日韩亚洲国产综合_久久久久久久久久久成人_在线区

首頁 > 數(shù)據(jù)庫 > Oracle > 正文

ORACLE自帶的JDBC源代碼解析

2024-08-29 13:49:10
字體:
供稿:網(wǎng)友

  
        大凡使用過JDBC連Oracle的人都會知道這樣一個(gè)事實(shí):我們需要的庫文件classes12.zip存在于$ORACLE_HOME/jdbc/lib目錄下(但仍有部分菜鳥每每在論壇上求此庫文件, 真是辛勞);但很少有人知道ORACLE還為我們預(yù)備了使用jdbc的示例,它存在于 $ORACLE_HOME/jdbc/demo/demo.zip 中。
        前一段時(shí)間,我學(xué)習(xí)ORACLE的OOP技術(shù),很受觸動。當(dāng)時(shí)我想:JDBC中一定存在某些OO技術(shù)以支持它。很久都沒有找到合適的例子,最后在ORACLE的安裝目錄下找到它。真可謂是:踏破鐵鞋無覓處,得來全不費(fèi)工夫。

        約定:
        1、假如出現(xiàn) java.lang.UnsatisfiedLinkError: do_open,則你需要把 DriverManager.getConnection() 方法的 url 修改成 jdbc:oracle:thin:@127.0.0.1:1521:oradb,具體原因未知;
        2、假如出現(xiàn) java.sql.SQLException: 不支持的字符集: oracle-character-set-852,則你需要把 nls_charset12.zip加入你的工程中(此文件與 classes12.zip 同目錄);

        下面我就把文件夾 amples/oci8/object-samples下的文件做一個(gè)具體的功能描述:
        1、PersonObject.java
        這個(gè)例子演示了表 people 中存在ADT字段 empid,其類型為 PERSON,而且類型 PERSON中存在ADT字段 home,其類型為 ADDRESS,而且類型 ADDRESS是一個(gè)ADT。
        假如使用常規(guī)SQL語句,其插入語句與在sql/plus中無異,即:使用構(gòu)造函數(shù)嵌套構(gòu)造。
        另有一種方法,使用 STRUCT 的構(gòu)造函數(shù) STRUCT(StructDescriptor, Connection, Object[]) 構(gòu)造出一個(gè)STRUCT對象,即一個(gè)ADT對象。同時(shí),假如有嵌套則需要嵌套構(gòu)造ADT對象。最后通過 PReparedStatement的 setObject方法指定ADT對象即可。
        讀取數(shù)據(jù)時(shí)則采用與上述方法相逆的辦法:假如是簡單類型,則直接讀??;假如是ADT,則使用ResultSet的getObject(),再強(qiáng)制轉(zhuǎn)換成STRUCT,然后調(diào)用STRUCT的getAttributes()方法取得 Object[] 類型數(shù)據(jù),如是遞歸。

        2、SQLDataExample.java與EmployeeObj.java
        此例與1中相似,也是對ADT的處理,不同的是類型沒有嵌套。
        比較而言,2比1的代碼簡潔了很多,不過也是付出了代價(jià):為類型 EMPLOYEE 抽象出一個(gè)類EmployeeObj,它實(shí)現(xiàn)了SQLData接口,并重寫了三個(gè)方法(必須的)。
        前臺的調(diào)用比1中的第二種方法簡潔了很多,只需要直接使用PreparedStatement的 setObject方法指定ADT對象即可(不過需要指定其類型為OracleTypes.STRUCT)。讀取時(shí)也可直接使用OracleResultSet的getObject()并強(qiáng)制轉(zhuǎn)換成EmployeeObj對象即可。
        真可謂是:有得必有失!!
        另,此例中有幾處需要注重的地方:
        2.1 EmployeeObj.java中的 import oracle.jdbc2.*; 改成 import oracle.jdbc.*; 原因未知;
        2.2 SQLDataExample.java 中的 Dictionary map = conn.getTypeMap(); 改成 java.util.Map map = conn.getTypeMap(); 原因:NOTE:  This class(指的是Dictionary) is obsolete. New implementations should implement the Map interface, rather than extendidng this class.(來源:javadoc);
        2.3 SQLDataExample.java 中的 pstmt.executeQuery(); 改成 pstmt.executeUpdate(); 更合理些,因?yàn)檫@是更新而非查詢(不改也不會影響功能,只是建議);

        3、CustomDatumExample.java與Employee.java
        此例與2完全相同。
不同的是采用了另外一種抽象技術(shù),并實(shí)現(xiàn)了接口CustomDatum 與 CustomDatumFactory,并重寫了二個(gè)方法toDatum()與create()。在前臺訪問數(shù)據(jù)時(shí)亦有少許不同:采用了OracleResultSet的getCustomDatum()方法并把它強(qiáng)制轉(zhuǎn)換成Employee。從外觀上看,2中SQLData接口存在于 java.sql.* 包中;而接口CustomDatum 與 CustomDatumFactory則存在于oracle.sql.*包中,可以認(rèn)為是Oracle公司對自己產(chǎn)品的專門實(shí)現(xiàn)?;蛟S有更高的性能、更小的開銷?不過3不如2來得直接,個(gè)人認(rèn)為。

        4、ArrayExample.java
        從文件名可看出,此示例演示的是VARRAY類型。
        同1,插入亦有兩種方法。一種可直接使用SQL;另外,可使用OraclePreparedStatement的setARRAY方法,構(gòu)造ARRAY的過程與構(gòu)造 STRUCT 無異。數(shù)據(jù)的讀取過程與此相反:先使用OracleResultSet的getARRAY()方法取得ARRAY對象,再調(diào)用此對象的getArray()方法并強(qiáng)制轉(zhuǎn)換成對象數(shù)組,然后對此數(shù)組操作即可。

        5、PersonRef.java與StudentRef.java
        不知是不是ORACLE與我們開玩笑,這兩個(gè)文件除了類名不同外,其余一切相同。
        這個(gè)例子給我們演示的是對象表的概念。對象表的插入與普通表沒有任何不同,數(shù)據(jù)的讀取首先體現(xiàn)在其SQL上,需要使用REF函數(shù),然后調(diào)用ResultSet的getObject()方法并強(qiáng)制轉(zhuǎn)換成REF對象,再利用此對象的getValue()并轉(zhuǎn)換成STRUCT對象,再利用此對象 的getAttributes()方法得到Object[],然后對此數(shù)組操作即可。

        6、RefClient.java與GenREF.java
        This sample demonstrates using REF over two different sessions.
        類GenREF用來封裝REF對象所指向的類型及其二進(jìn)制內(nèi)容。程序先Materialize into GenREF,然后在另一會話中De-materialize REF from GenREF,下面就與處理REF相同:利用此對象的getValue()并轉(zhuǎn)換成STRUCT對象,再利用此對象 的getAttributes()方法得到Object[],然后對此數(shù)組操作即可。

        7、FileExample.java與PLSQL_FileExample.java
        此示例使用 BFILE 數(shù)據(jù)類型,Contains a locator(定位器) to a large binary file stored outside the database。數(shù)據(jù)插入時(shí)需要使用函數(shù) bfilename,這個(gè)函數(shù)需要目錄對象,此對象需要使用create Directory mydir來創(chuàng)建(此用戶需具有CREATE ANY DIRECTORY系統(tǒng)權(quán)限)。我曾在這個(gè)地方有個(gè)大教訓(xùn):按著步驟做,可在讀取時(shí)總是提示我沒有此目錄!!最后,我把BFILENAME函數(shù)的第一個(gè)參數(shù)(即目錄名)大寫就好了。原因:目錄名在函數(shù)中區(qū)分大小寫,雖然我們創(chuàng)建它時(shí)用的是小寫,可到了數(shù)據(jù)庫中后就自動變成了大寫。
        讀取BFILE類型的數(shù)據(jù)時(shí),首先通過其getBinaryStream()方法得到二進(jìn)制的輸入流,然后操作這個(gè)輸入流就可以了。The limitation is your imagination。
        PLSQL_FileExample.java實(shí)現(xiàn)的功能與上述的相同,只不過所有針對BFILE的操作都是通過調(diào)用pl/sql匿名塊來完成的,并使用了OracleCallableStatement。假如沒有必要,使用前者即可。

        8、LobExample.java與PLSQL_LobExample.java
        此示例使用了CLOB和BLOB數(shù)據(jù)類型。
        插入數(shù)據(jù)時(shí),需要分別通過getBinaryOutputStream()和getCharacterOutputStream()得到二進(jìn)制輸出流和字符輸出流,然后就是針對此輸出流的操作了,與傳統(tǒng)的 java I/O 相同。
        讀取數(shù)據(jù)時(shí),需要分別通過getBinaryStream()和getCharacterStream()得到二進(jìn)制輸入流和字符輸入流,然后就是針對此輸入流的操作了,與傳統(tǒng)的 java I/O 相同。
        PLSQL_LobExample.java實(shí)現(xiàn)的功能與上述的相同,只不過所有針對CLOB和BLOB的操作都是通過調(diào)用pl/sql匿名塊來完成的,并使用了OracleCallableStatement。
假如沒有必要,使用前者即可。
    
        注:7、8的第二個(gè)示例中均使用到了dbms_lob程序包。

        上面我僅對ORACLE給我們提供的demo的極小的一部分給出了解釋,并加入我自己的看法。我也是想通過這篇文章,起到拋磚引玉的作用,希望廣大網(wǎng)友多對產(chǎn)品的示例進(jìn)行分析,從而得到最原汁原味的代碼。

        你的意見,我愿意聽!! email:zbdlmxc@163.com

發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 日韩3级| 日本精品视频 | 美日韩一区二区三区 | 国产99久久 | 99视频精品| 自拍偷拍视频网 | 亚洲精品电影在线观看 | 日韩欧美一区二区视频 | 一区二区三区日本 | 国产极品美女在线 | 亚洲欧美电影 | 黄色在线免费观看视频网站 | 日韩精品播放 | 成人在线观看免费爱爱 | 久草精品在线观看 | 看毛片的网站 | 亚洲日本中文 | 中文字幕在线精品 | 成人a在线| 天堂视频中文字幕 | 亚洲精品久久久久久久久久 | 免费a视频在线 | 精品久久网| 亚洲综合国产激情另类一区 | 成人免费视频视频在线观看 免费 | 久久久91精品国产一区二区三区 | 欧美极品一区二区三区 | 99精品欧美一区二区三区综合在线 | 一区二区三区国产亚洲网站 | 夜夜天天操 | 中文字幕在线观看精品视频 | 日本中文字幕电影 | 91亚洲国产成人久久精品网站 | 国产精品免费在线 | 国产精品一区二区av | 久久久xxxx | 91伊人| 亚洲成人精品 | 国产女爽123视频.cno | 国产欧美日本 | 精品三级在线观看 |