网络编程 | 站长之家 | 网页制作 | 图形图象 | 操作系统 | 冲浪宝典 | 软件教学 | 网络办公 | 邮件系统 | 网络安全 | 认证考试 | 系统进程
Firefox | IE | Maxthon | 迅雷 | 电驴 | BitComet | FlashGet | QQ | QQ空间 | Vista | 输入法 | Ghost | Word | Excel | wps | Powerpoint
asp | .net | php | jsp | Sql | c# | Ajax | xml | Dreamweaver | FrontPages | Javascript | css | photoshop | fireworks | Flash | Cad | Discuz!
当前位置 > 网站建设学院 > 网络编程 > 数据库 > Oracle教程
Tag:注入,存储过程,分页,安全,优化,xmlhttp,fso,jmail,application,session,防盗链,stream,无组件,组件,md5,乱码,缓存,加密,验证码,算法,cookies,ubb,正则表达式,水印,索引,日志,压缩,base64,url重写,上传,控件,Web.config,JDBC,函数,内存,PDF,迁移,结构,破解,编译,配置,进程,分词,IIS,Apache,Tomcat,phpmyadmin,Gzip,触发器,socket
数据库:数据库教程,数据库技巧,Oracle教程,MySQL教程,Sybase教程,Access教程,DB2教程,数据库安全,数据库文摘
本月文章推荐
.案例学习Oracle错误:ORA-00904.
.Weblogic8配置Oracle数据库连接池.
.Java开发使用Oracle数据库的注意.
.在Oracle 10g中如何获得索引建议.
.配置Windows与Linux平台的DATA G.
.ORACLE 面试问题-技术篇(1).
.Oracle索引表的使用(Table Inde.
.oracle817视图中object_type的&#.
.Oracle8 数据类型.
.ExactPapers Oracle 1Z0-007 200.
.Oracle高手必读,不要错过噢!.
.过程,函数,程序包.
.SGA内参数设置.
.数据库容灾复制解决方案share Pl.
.一些 schema 的常用脚本归类介绍.
.Oracle监听器启动路径为空导致服.
.Linux 网管 123 --- 升级 Linux.
.Oracle 9i 在AIX 5L 上的安装、建.
.解析:Oracle 10g EM Database C.
.ORACLE SGA分配.

ORACLE自带的JDBC源代码解析

发表日期:2008-2-9



  
        大凡使用过JDBC连Oracle的人都会知道这样一个事实:我们需要的库文件classes12.zip存在于$ORACLE_HOME/jdbc/lib目录下(但仍有部分菜鸟每每在论坛上求此库文件, 真是辛劳);但很少有人知道ORACLE还为我们预备了使用jdbc的示例,它存在于 $ORACLE_HOME/jdbc/demo/demo.zip 中。
        前一段时间,我学习ORACLE的OOP技术,很受触动。当时我想:JDBC中一定存在某些OO技术以支持它。很久都没有找到合适的例子,最后在ORACLE的安装目录下找到它。真可谓是:踏破铁鞋无觅处,得来全不费工夫。

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

        下面我就把文件夹 amples\oci8\object-samples下的文件做一个具体的功能描述:
        1、PersonObject.java
        这个例子演示了表 people 中存在ADT字段 empid,其类型为 PERSON,而且类型 PERSON中存在ADT字段 home,其类型为 ADDRESS,而且类型 ADDRESS是一个ADT。
        假如使用常规SQL语句,其插入语句与在sql/plus中无异,即:使用构造函数嵌套构造。
        另有一种方法,使用 STRUCT 的构造函数 STRUCT(StructDescriptor, Connection, Object[]) 构造出一个STRUCT对象,即一个ADT对象。同时,假如有嵌套则需要嵌套构造ADT对象。最后通过 PreparedStatement的 setObject方法指定ADT对象即可。
        读取数据时则采用与上述方法相逆的办法:假如是简单类型,则直接读取;假如是ADT,则使用ResultSet的getObject(),再强制转换成STRUCT,然后调用STRUCT的getAttributes()方法取得 Object[] 类型数据,如是递归。

        2、SQLDataExample.java与EmployeeObj.java
        此例与1中相似,也是对ADT的处理,不同的是类型没有嵌套。
        比较而言,2比1的代码简洁了很多,不过也是付出了代价:为类型 EMPLOYEE 抽象出一个类EmployeeObj,它实现了SQLData接口,并重写了三个方法(必须的)。
        前台的调用比1中的第二种方法简洁了很多,只需要直接使用PreparedStatement的 setObject方法指定ADT对象即可(不过需要指定其类型为OracleTypes.STRUCT)。读取时也可直接使用OracleResultSet的getObject()并强制转换成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(); 更合理些,因为这是更新而非查询(不改也不会影响功能,只是建议);

        3、CustomDatumExample.java与Employee.java
        此例与2完全相同。
不同的是采用了另外一种抽象技术,并实现了接口CustomDatum 与 CustomDatumFactory,并重写了二个方法toDatum()与create()。在前台访问数据时亦有少许不同:采用了OracleResultSet的getCustomDatum()方法并把它强制转换成Employee。从外观上看,2中SQLData接口存在于 java.sql.* 包中;而接口CustomDatum 与 CustomDatumFactory则存在于oracle.sql.*包中,可以认为是Oracle公司对自己产品的专门实现。或许有更高的性能、更小的开销?不过3不如2来得直接,个人认为。

        4、ArrayExample.java
        从文件名可看出,此示例演示的是VARRAY类型。
        同1,插入亦有两种方法。一种可直接使用SQL;另外,可使用OraclePreparedStatement的setARRAY方法,构造ARRAY的过程与构造 STRUCT 无异。数据的读取过程与此相反:先使用OracleResultSet的getARRAY()方法取得ARRAY对象,再调用此对象的getArray()方法并强制转换成对象数组,然后对此数组操作即可。

        5、PersonRef.java与StudentRef.java
        不知是不是ORACLE与我们开玩笑,这两个文件除了类名不同外,其余一切相同。
        这个例子给我们演示的是对象表的概念。对象表的插入与普通表没有任何不同,数据的读取首先体现在其SQL上,需要使用REF函数,然后调用ResultSet的getObject()方法并强制转换成REF对象,再利用此对象的getValue()并转换成STRUCT对象,再利用此对象 的getAttributes()方法得到Object[],然后对此数组操作即可。

        6、RefClient.java与GenREF.java
        This sample demonstrates using REF over two different Sessions.
        类GenREF用来封装REF对象所指向的类型及其二进制内容。程序先Materialize into GenREF,然后在另一会话中De-materialize REF from GenREF,下面就与处理REF相同:利用此对象的getValue()并转换成STRUCT对象,再利用此对象 的getAttributes()方法得到Object[],然后对此数组操作即可。

        7、FileExample.java与PLSQL_FileExample.java
        此示例使用 BFILE 数据类型,Contains a locator(定位器) to a large binary file stored outside the database。数据插入时需要使用函数 bfilename,这个函数需要目录对象,此对象需要使用create Directory mydir来创建(此用户需具有CREATE ANY DIRECTORY系统权限)。我曾在这个地方有个大教训:按着步骤做,可在读取时总是提示我没有此目录!!最后,我把BFILENAME函数的第一个参数(即目录名)大写就好了。原因:目录名在函数中区分大小写,虽然我们创建它时用的是小写,可到了数据库中后就自动变成了大写。
        读取BFILE类型的数据时,首先通过其getBinaryStream()方法得到二进制的输入流,然后操作这个输入流就可以了。The limitation is your imagination。
        PLSQL_FileExample.java实现的功能与上述的相同,只不过所有针对BFILE的操作都是通过调用pl/sql匿名块来完成的,并使用了OracleCallableStatement。假如没有必要,使用前者即可。

        8、LobExample.java与PLSQL_LobExample.java
        此示例使用了CLOB和BLOB数据类型。
        插入数据时,需要分别通过getBinaryOutputStream()和getCharacterOutputStream()得到二进制输出流和字符输出流,然后就是针对此输出流的操作了,与传统的 java I/O 相同。
        读取数据时,需要分别通过getBinaryStream()和getCharacterStream()得到二进制输入流和字符输入流,然后就是针对此输入流的操作了,与传统的 java I/O 相同。
        PLSQL_LobExample.java实现的功能与上述的相同,只不过所有针对CLOB和BLOB的操作都是通过调用pl/sql匿名块来完成的,并使用了OracleCallableStatement。
假如没有必要,使用前者即可。
    
        注:7、8的第二个示例中均使用到了dbms_lob程序包。

        上面我仅对ORACLE给我们提供的demo的极小的一部分给出了解释,并加入我自己的看法。我也是想通过这篇文章,起到抛砖引玉的作用,希望广大网友多对产品的示例进行分析,从而得到最原汁原味的代码。

        你的意见,我愿意听!! email:zbdlmxc@163.com
上一篇:oracle的几个使用技巧 人气:591
下一篇:在sqlplus环境中对自己的动作和结果进行记录 人气:622
浏览全部Oracle教程的内容 Dreamweaver插件下载 网页广告代码 祝你圣诞节快乐 2009年新年快乐